增加RBG聚类

pull/22/head
thenk008 5 years ago
parent 1a64279d4c
commit b955bb673f

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="Maven: com.alibaba:fastjson:1.2.51" level="project" />
</component>
</module>

@ -10,8 +10,7 @@ import org.wlld.imageRecognition.modelEntity.RegressionBody;
import org.wlld.tools.ArithUtil;
import org.wlld.tools.Frequency;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
/**
* @author lidapeng
@ -19,6 +18,8 @@ import java.util.List;
* @date 9:23 2020/1/2
*/
public class Convolution extends Frequency {
private MeanClustering meanClustering;
protected Matrix getFeatures(Matrix matrix, int maxNub, TempleConfig templeConfig
, int id) throws Exception {
boolean isFirst = true;
@ -39,6 +40,88 @@ public class Convolution extends Frequency {
return matrix;
}
public void kc(ThreeChannelMatrix threeChannelMatrix, int size, int sqNub) throws Exception {
Matrix matrixR = threeChannelMatrix.getMatrixR();
Matrix matrixG = threeChannelMatrix.getMatrixG();
Matrix matrixB = threeChannelMatrix.getMatrixB();
matrixR = late(matrixR, size);
matrixG = late(matrixG, size);
matrixB = late(matrixB, size);
int x = matrixR.getX();
int y = matrixR.getY();
meanClustering = new MeanClustering(sqNub);
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
double[] color = new double[]{matrixR.getNumber(i, j) / 255, matrixG.getNumber(i, j) / 255, matrixB.getNumber(i, j) / 255};
meanClustering.setColor(color);
}
}
meanClustering.start();
List<RGBNorm> rgbNorms = meanClustering.getMatrices();
double minNorm = 0;
int normSize = rgbNorms.size();
for (int i = 0; i < normSize; i++) {
RGBNorm rgbNorm = rgbNorms.get(i);
double[] rgb = rgbNorm.getRgb();
for (int j = 0; j < normSize; j++) {
if (j != i) {
double normSub = getEDist(rgb, rgbNorms.get(j).getRgb());
if (minNorm == 0 || normSub < minNorm) {
minNorm = normSub;
}
}
}
}
minNorm = ArithUtil.div(minNorm, 2);
System.out.println("min==" + minNorm);
}
private void checkImage(Matrix matrixR, Matrix matrixG, Matrix matrixB, double minNorm, int size) {
List<List<Double>> lists = new ArrayList<>();
int x = matrixR.getX() - size;//求导后矩阵的行数
int y = matrixR.getY() - size;//求导后矩阵的列数
for (int i = 0; i < x; i += size) {//遍历行
for (int j = 0; j < y; j += size) {//遍历每行的列
Matrix myMatrixR = matrixR.getSonOfMatrix(i, j, size, size);
Matrix myMatrixG = matrixG.getSonOfMatrix(i, j, size, size);
Matrix myMatrixB = matrixB.getSonOfMatrix(i, j, size, size);
}
}
}
private void getListFeature(Matrix matrixR, Matrix matrixG, Matrix matrixB, double minNorm) throws Exception {
int x = matrixR.getX();
int y = matrixR.getY();
Map<Double, Integer> map = new HashMap<>();
List<RGBNorm> rgbNormList = meanClustering.getMatrices();
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
double[] color = new double[]{matrixR.getNumber(i, j) / 255, matrixG.getNumber(i, j) / 255, matrixB.getNumber(i, j) / 255};
int id = -1;
double feature = 0;
double minDist = 0;
for (int t = 0; t < rgbNormList.size(); t++) {
RGBNorm rgbNorm = rgbNormList.get(t);
double dist = getEDist(color, rgbNorm.getRgb());
if (minDist == 0 || dist < minDist) {
minDist = dist;
id = t;
}
}
if (minDist >= minNorm) {
id = -1;
}
if (id > -1) {
feature = rgbNormList.get(id).getNorm();
}
if (!map.containsKey(feature)) {
map.put(feature, 1);
}
}
}
}
public List<List<Double>> imageTrance(Matrix matrix, int size, int featureNub) throws Exception {//矩阵和卷积核大小
int xn = matrix.getX();
int yn = matrix.getY();
@ -160,14 +243,18 @@ public class Convolution extends Frequency {
for (int j = 0; j < yn - size; j += size) {
Matrix matrix1 = matrix.getSonOfMatrix(i, j, size, size);
double maxNub = 0;
int n = size * size;
double sigma = 0;
for (int t = 0; t < matrix1.getX(); t++) {
for (int k = 0; k < matrix1.getY(); k++) {
double nub = matrix1.getNumber(t, k);
sigma = sigma + nub;
if (nub > maxNub) {
maxNub = nub;
}
}
}
maxNub = ArithUtil.div(sigma, n);
//迟化的最大值是 MAXNUB
myMatrix.setNub(i / size, j / size, maxNub);
}

@ -0,0 +1,96 @@
package org.wlld.imageRecognition;
import java.util.*;
//K均值聚类
public class MeanClustering {
private List<double[]> matrixList = new ArrayList<>();//聚类集合
private int length;//向量长度(模型需要返回)
private int speciesQuantity;//种类数量(模型需要返回)
private List<RGBNorm> matrices = new ArrayList<>();//均值K模型(模型需要返回)
public List<RGBNorm> getMatrices() {
return matrices;
}
public MeanClustering(int speciesQuantity) {
this.speciesQuantity = speciesQuantity;//聚类的数量
}
public void setColor(double[] color) throws Exception {
if (matrixList.size() == 0) {
matrixList.add(color);
length = color.length;
} else {
if (length == color.length) {
matrixList.add(color);
} else {
throw new Exception("vector length is different");
}
}
}
private void averageMatrix() {
for (double[] rgb : matrixList) {//遍历当前集合
double min = -1;
int id = 0;
for (int i = 0; i < speciesQuantity; i++) {
RGBNorm rgbNorm = matrices.get(i);
double dist = rgbNorm.getEDist(rgb);
if (min == -1 || dist < min) {
min = dist;
id = i;
}
}
//进簇
RGBNorm rgbNorm = matrices.get(id);
rgbNorm.setColor(rgb);
}
//重新计算均值
for (RGBNorm rgbNorm : matrices) {
rgbNorm.norm();
}
}
private boolean isNext() {
boolean isNext = false;
for (RGBNorm rgbNorm : matrices) {
isNext = rgbNorm.compare();
if (isNext) {
break;
}
}
return isNext;
}
private void clear() {
for (RGBNorm rgbNorm : matrices) {
rgbNorm.clear();
}
}
public void start() throws Exception {//开始聚类
if (matrixList.size() > 1) {
Random random = new Random();
for (int i = 0; i < speciesQuantity; i++) {//初始化均值向量
int index = random.nextInt(matrixList.size());
double[] rgb = matrixList.get(index);
RGBNorm rgbNorm = new RGBNorm(rgb);
//要进行深度克隆
matrices.add(rgbNorm);
}
//进行两者的比较
boolean isNext;
do {
averageMatrix();
isNext = isNext();
if (isNext) {
clear();
}
}
while (isNext);
} else {
throw new Exception("matrixList number less than 2");
}
}
}

@ -0,0 +1,84 @@
package org.wlld.imageRecognition;
import org.wlld.tools.ArithUtil;
import java.util.Arrays;
public class RGBNorm {
private double[] rgbAll = new double[3];
private double norm;
private int nub;
private double[] rgb = new double[3];
private double[] rgbUp;
RGBNorm(double[] rgb) {
this.rgbUp = rgb;
}
public void syn() {
rgbUp = rgb;
}
public void clear() {
rgbAll = new double[3];
nub = 0;
for (int i = 0; i < rgb.length; i++) {
rgbUp[i] = rgb[i];
}
//System.out.println("clear==" + Arrays.toString(rgbUp));
}
public int getNub() {
return nub;
}
public boolean compare() {
boolean isNext = false;
for (int i = 0; i < rgb.length; i++) {
if (rgb[i] != rgbUp[i]) {
isNext = true;
break;
}
}
return isNext;
}
public double getEDist(double[] x) {
double[] y = new double[x.length];
for (int i = 0; i < y.length; i++) {
y[i] = x[i] - rgbUp[i];
}
double sigma = 0;
for (int i = 0; i < y.length; i++) {
sigma = sigma + Math.pow(y[i], 2);
}
return Math.sqrt(sigma);
}
public void setColor(double[] rgb) {
for (int i = 0; i < rgb.length; i++) {
rgbAll[i] = rgbAll[i] + rgb[i];
}
nub++;
}
public void norm() {//范长计算
double sigma = 0;
if (nub > 0) {
for (int i = 0; i < rgb.length; i++) {
double rgbc = ArithUtil.div(rgbAll[i], nub);
rgb[i] = rgbc;
sigma = sigma + Math.pow(rgbc, 2);
}
norm = Math.sqrt(sigma);
}
}
public double getNorm() {
return norm;
}
public double[] getRgb() {
return rgb;
}
}

@ -60,7 +60,7 @@ public class KClustering {
}
public KClustering(int speciesQuantity) {
this.speciesQuantity = speciesQuantity;
this.speciesQuantity = speciesQuantity;//聚类的数量
matrices = new Matrix[speciesQuantity];
for (int i = 0; i < speciesQuantity; i++) {
clusterMap.put(i, new ArrayList<>());
@ -163,8 +163,7 @@ public class KClustering {
matrices[i] = matrixList.get(index).getMatrix();
}
//进行两者的比较
boolean isEqual = false;
int nub = 0;
boolean isEqual;
do {
Matrix[] matrices2 = averageMatrix();
isEqual = equals(matrices, matrices2);
@ -172,7 +171,6 @@ public class KClustering {
matrices = matrices2;
clear();
}
nub++;
}
while (!isEqual);
//聚类结束,进行坐标均值矩阵计算

@ -1,6 +1,7 @@
package org.wlld.imageRecognition.segmentation;
import org.wlld.MatrixTools.Matrix;
import org.wlld.imageRecognition.ThreeChannelMatrix;
import java.util.HashMap;
import java.util.Map;
@ -11,14 +12,26 @@ import java.util.Map;
* @date 10:25 2020/1/13
*/
public class ImageSegmentation {
private Matrix regionMap;
private Matrix matrix;
private Matrix matrixR;
private Matrix matrixG;
private Matrix matrixB;
private Map<Integer, RegionBody> regionBodyList = new HashMap<>();
private int id = 1;
public ImageSegmentation(Matrix matrix) {
this.matrix = matrix;
regionMap = new Matrix(matrix.getX(), matrix.getY());
public ImageSegmentation(ThreeChannelMatrix threeChannelMatrix) throws Exception {
matrixR = threeChannelMatrix.getMatrixR();
matrixG = threeChannelMatrix.getMatrixG();
matrixB = threeChannelMatrix.getMatrixB();
int x = matrixR.getX();
int y = matrixR.getY();
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
double r = matrixR.getNumber(i, j);
double g = matrixG.getNumber(i, j);
double b = matrixB.getNumber(i, j);
}
}
}
public int getMin(double[] array) {
@ -33,106 +46,4 @@ public class ImageSegmentation {
return minIdx;
}
private void connect(int x, int y) throws Exception {
double self = matrix.getNumber(x, y);
double rightPixel = matrix.getNumber(x, y + 1);
double leftPixel = matrix.getNumber(x, y - 1);
double bottomPixel = matrix.getNumber(x + 1, y);
double topPixel = matrix.getNumber(x - 1, y);
double right = Math.abs(rightPixel - self);
double left = Math.abs(leftPixel - self);
double bottom = Math.abs(bottomPixel - self);
double top = Math.abs(topPixel - self);
double[] array = new double[]{left, right, top, bottom};
double[] pixelArray = new double[]{leftPixel, rightPixel, topPixel, bottomPixel};
int minIndex = getMin(array);
int i, j;
switch (minIndex) {
case 0:
i = x;
j = y - 1;
break;
case 1:
i = x;
j = y + 1;
break;
case 2:
i = x - 1;
j = y;
break;
case 3:
i = x + 1;
j = y;
break;
default:
throw new IllegalStateException("Unexpected value: " + minIndex);
}
int type = (int) regionMap.getNumber(i, j);
if (type > 0) {//有选区了
RegionBody regionBody = regionBodyList.get(type);
regionBody.insertPosition(x, y, regionMap);
regionBody.setPixel(self);
} else {//链接最小方向的节点没有属于任何区域
RegionBody regionBody = new RegionBody(id);
regionBody.insertPosition(x, y, regionMap);
regionBody.insertPosition(i, j, regionMap);
regionBody.setPixel(pixelArray[minIndex]);
regionBody.setPixel(self);
regionBodyList.put(id, regionBody);
id++;
}
}
public void createMST() throws Exception {
int x = matrix.getX() - 1;
int y = matrix.getY() - 1;
for (int i = 1; i < x; i++) {
for (int j = 1; j < y; j++) {
if (regionMap.getNumber(i, j) == 0.0) {
connect(i, j);
}
}
}
for (int i = 0; i < 3; i++) {
mergeMSTX();
}
}
private void mergeMSTX() throws Exception {//合并选区
int x = matrix.getX() - 1;
int y = matrix.getY() - 1;
int now = (int) regionMap.getNumber(1, 1);
int nowX = 1;
int nowY = 1;
for (int i = 1; i < x; i++) {
for (int j = 1; j < y; j++) {
int self = (int) regionMap.getNumber(i, j);
if (now != self) {//遇到不同选区 区域NOW尝试与区域self合并
double nowPoint = matrix.getNumber(nowX, nowY);
double selfPoint = matrix.getNumber(i, j);
RegionBody nowMST = regionBodyList.get(now);
RegionBody selfMST = regionBodyList.get(self);
double nowDiff = nowMST.getMaxDiff();
double selfDiff = selfMST.getMaxDiff();
double diff = Math.abs(nowPoint - selfPoint);//当前边的差异性
double minDiff;
if (nowDiff > selfDiff) {//差异性最小的是SELF
minDiff = selfDiff;
} else {//差异性最小的是NOW
minDiff = nowDiff;
}
if (diff <= minDiff) {//进行合并
nowMST.merge(selfMST, regionMap);
regionBodyList.remove(self);
} else {//不进行合并
now = self;
}
}
nowX = i;
nowY = j;
}
}
}
}

@ -10,99 +10,5 @@ import java.util.List;
* @description
*/
public class RegionBody {
private int minX = -1;
private int maxX = -1;
private int minY = -1;
private int maxY = -1;
private int point = 0xFFF;
private int bit = 4 * 3;
private int id;//本区域主键
private double minPixel = -1;//最小像素值
private double maxPixel = 0;//最大像素值
private List<Integer> pixels = new ArrayList<>();
public int getMinX() {
return minX;
}
public int getMaxX() {
return maxX;
}
public int getMinY() {
return minY;
}
public int getMaxY() {
return maxY;
}
RegionBody(int id) {
this.id = id;
}
public double getMaxDiff() {
return maxPixel - minPixel;
}
public int getHeight() {
return maxX - minX;
}
public int getWidth() {
return maxY - minY;
}
public void merge(RegionBody body, Matrix regionMap) throws Exception {//合并区域
List<Integer> myPixels = body.getPixels();
setPixel(body.getMaxPixel());
setPixel(body.getMinPixel());
for (int pixel : myPixels) {
int x = pixel >> bit;
int y = pixel & point;
insertPosition(x, y, regionMap);
}
}
public void setPixel(double pixel) {
if (pixel < minPixel || minPixel == -1) {
minPixel = pixel;
}
if (pixel > maxPixel) {
maxPixel = pixel;
}
}
public void insertPosition(int x, int y, Matrix regionMap) throws Exception {
if (x < minX || minX == -1) {
minX = x;
}
if (y < minY || minY == -1) {
minY = y;
}
if (x > maxX) {
maxX = x;
}
if (y > maxY) {
maxY = y;
}
//行在前,列在后
int pixel = x << bit | y;
pixels.add(pixel);
//给区域地图中的像素分配区域ID
regionMap.setNub(x, y, id);
}
public double getMinPixel() {
return minPixel;
}
public double getMaxPixel() {
return maxPixel;
}
public List<Integer> getPixels() {
return pixels;
}
}

@ -14,6 +14,18 @@ public abstract class Frequency {//统计频数
return allNub;
}
public double getEDist(double[] x1, double[] x2) {//返回两个等长数组之间的欧式距离
double[] y = new double[x1.length];
for (int i = 0; i < y.length; i++) {
y[i] = x1[i] - x2[i];
}
double sigma = 0;
for (int i = 0; i < y.length; i++) {
sigma = sigma + Math.pow(y[i], 2);
}
return Math.sqrt(sigma);
}
public double averageByList(List<Double> m) {//计算平均值
int len = m.size();
double allNub = 0;

@ -7,12 +7,11 @@ import org.wlld.ModelData;
import org.wlld.config.RZ;
import org.wlld.config.StudyPattern;
import org.wlld.function.Sigmod;
import org.wlld.imageRecognition.Operation;
import org.wlld.imageRecognition.Picture;
import org.wlld.imageRecognition.TempleConfig;
import org.wlld.imageRecognition.*;
import org.wlld.nerveEntity.ModelParameter;
import org.wlld.tools.ArithUtil;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -23,7 +22,7 @@ import java.util.Map;
*/
public class CoverTest {
public static void main(String[] args) throws Exception {
cover();
cover2();
//test(null, 25, 3);
}
@ -107,6 +106,14 @@ public class CoverTest {
System.out.println("wrongPoint==" + wrongPoint + "%");
}
public static void cover2() throws Exception {
Convolution convolution = new Convolution();
Picture picture = new Picture();
ThreeChannelMatrix threeChannelMatrix = picture.getThreeMatrix("D:\\docment/a.jpg");
convolution.kc(threeChannelMatrix, 5, 5);
}
//覆盖率学习 有学习才能有识别
public static void cover() throws Exception {
//创建图片解析类 桔梗覆盖,桔梗焚烧,土壤扰动

Loading…
Cancel
Save