commit
50553eb374
@ -0,0 +1,7 @@
|
||||
package org.wlld.i;
|
||||
|
||||
public interface PsoFunction {//粒子群回调函数
|
||||
|
||||
//根据参数返回函数值
|
||||
double getResult(double[] parameter,int id) throws Exception;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,163 @@
|
||||
package org.wlld.imageRecognition;
|
||||
|
||||
|
||||
import org.wlld.MatrixTools.Matrix;
|
||||
import org.wlld.imageRecognition.border.GMClustering;
|
||||
import org.wlld.imageRecognition.modelEntity.GMBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class CutFood {
|
||||
private TempleConfig templeConfig;
|
||||
private Map<Integer, GMClustering> meanMap;//干食混高模型
|
||||
private Matrix regionMap;
|
||||
private double foodFilterTh;
|
||||
|
||||
public CutFood(TempleConfig templeConfig, Map<Integer, GMClustering> meanMap) {
|
||||
this.templeConfig = templeConfig;
|
||||
foodFilterTh = templeConfig.getFood().getFoodFilterTh();
|
||||
this.meanMap = meanMap;
|
||||
}
|
||||
|
||||
private void mean(ThreeChannelMatrix threeChannelMatrix, GMClustering mean) throws Exception {
|
||||
Matrix matrixR = threeChannelMatrix.getMatrixR();
|
||||
Matrix matrixG = threeChannelMatrix.getMatrixG();
|
||||
Matrix 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[] rgb = new double[]{matrixR.getNumber(i, j) / 255, matrixG.getNumber(i, j) / 255
|
||||
, matrixB.getNumber(i, j) / 255};
|
||||
mean.setColor(rgb);
|
||||
}
|
||||
}
|
||||
mean.start();
|
||||
}
|
||||
|
||||
private double getAvg(Matrix matrix) throws Exception {
|
||||
double sigma = 0;
|
||||
int x = matrix.getX();
|
||||
int y = matrix.getY();
|
||||
for (int i = 0; i < x; i++) {
|
||||
for (int j = 0; j < y; j++) {
|
||||
sigma = sigma + matrix.getNumber(i, j);
|
||||
}
|
||||
}
|
||||
return sigma / (x * y);
|
||||
}
|
||||
|
||||
private void getAvgPro(ThreeChannelMatrix threeChannelMatrix) throws Exception {
|
||||
int size = templeConfig.getFood().getRegionSize();
|
||||
Matrix matrixR = threeChannelMatrix.getMatrixR();
|
||||
Matrix matrixG = threeChannelMatrix.getMatrixG();
|
||||
Matrix matrixB = threeChannelMatrix.getMatrixB();
|
||||
int x = matrixR.getX();
|
||||
int y = matrixR.getY();
|
||||
regionMap = new Matrix(x / size, y / size);
|
||||
for (int i = 0; i <= x - size; i += size) {
|
||||
for (int j = 0; j <= y - size; j += size) {
|
||||
double r = getAvg(matrixR.getSonOfMatrix(i, j, size, size));
|
||||
double g = getAvg(matrixG.getSonOfMatrix(i, j, size, size));
|
||||
double b = getAvg(matrixB.getSonOfMatrix(i, j, size, size));
|
||||
double[] rgb = new double[]{r / 255, g / 255, b / 255};
|
||||
int index = getType(rgb);
|
||||
regionMap.setNub(i / size, j / size, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getTypeNub(ThreeChannelMatrix threeChannelMatrix
|
||||
, int myType) throws Exception {
|
||||
getAvgPro(threeChannelMatrix);
|
||||
return getTypeNub(myType);
|
||||
}
|
||||
|
||||
private Map<Integer, Integer> getTypeNub(int myType) throws Exception {
|
||||
int size = templeConfig.getFood().getRegionSize();
|
||||
double s = Math.pow(size, 2);
|
||||
int xr = regionMap.getX();
|
||||
int yr = regionMap.getY();
|
||||
List<GMBody> gmBodies = new ArrayList<>();
|
||||
for (int i = 0; i < xr; i++) {
|
||||
for (int j = 0; j < yr; j++) {
|
||||
int type = (int) regionMap.getNumber(i, j);
|
||||
if (!insertBodies(gmBodies, i, j, type)) {//需要创建一个新的
|
||||
gmBodies.add(new GMBody(type, i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<Integer, Integer> gmTypeNub = new HashMap<>();
|
||||
for (int i = 0; i < gmBodies.size(); i++) {//过滤侯选区
|
||||
GMBody gmBody = gmBodies.get(i);
|
||||
double regionSize = gmBody.getPixelNub() * s;
|
||||
int type = gmBody.getType();
|
||||
if (type != 1) {//背景直接过滤
|
||||
double oneSize = meanMap.get(type).getRegionSize();
|
||||
int nub = (int) (regionSize / oneSize);//数量
|
||||
if (nub > 0) {
|
||||
if (gmTypeNub.containsKey(type)) {
|
||||
int myNub = gmTypeNub.get(type);
|
||||
if (nub > myNub) {
|
||||
gmTypeNub.put(type, nub);
|
||||
}
|
||||
} else {
|
||||
gmTypeNub.put(type, nub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gmTypeNub.size() == 0) {
|
||||
gmTypeNub.put(myType, 1);
|
||||
}
|
||||
return gmTypeNub;
|
||||
}
|
||||
|
||||
private boolean insertBodies(List<GMBody> gmBodies, int x, int y, int type) {
|
||||
boolean isInsert = false;
|
||||
for (GMBody gmBody : gmBodies) {
|
||||
if (gmBody.insertRgb(x, y, type)) {
|
||||
isInsert = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isInsert;
|
||||
}
|
||||
|
||||
private int getType(double[] rgb) throws Exception {
|
||||
int index = 0;
|
||||
double max = 0;
|
||||
for (Map.Entry<Integer, GMClustering> entry : meanMap.entrySet()) {
|
||||
GMClustering gmClustering = entry.getValue();
|
||||
double probability = gmClustering.getProbabilityDensity(rgb);
|
||||
if (probability > max) {
|
||||
max = probability;
|
||||
index = entry.getKey();
|
||||
}
|
||||
}
|
||||
if (max < 2) {
|
||||
index = 1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public void study(int type, ThreeChannelMatrix threeChannelMatrix) throws Exception {
|
||||
Matrix matrixR = threeChannelMatrix.getMatrixR();
|
||||
int x = matrixR.getX();
|
||||
int y = matrixR.getY();
|
||||
GMClustering mean = new GMClustering(templeConfig.getFeatureNub());
|
||||
mean.setRegionSize(x * y * foodFilterTh);
|
||||
meanMap.put(type, mean);
|
||||
mean(threeChannelMatrix, mean);
|
||||
//记录非背景的单物体面积
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package org.wlld.imageRecognition;
|
||||
|
||||
import org.wlld.imageRecognition.modelEntity.MappingBody;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class MappingSort implements Comparator<MappingBody> {
|
||||
@Override
|
||||
public int compare(MappingBody o1, MappingBody o2) {
|
||||
if (o1.getMappingNub() > o2.getMappingNub()) {
|
||||
return -1;
|
||||
} else if (o1.getMappingNub() < o2.getMappingNub()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,33 +0,0 @@
|
||||
package org.wlld.imageRecognition;
|
||||
|
||||
import org.wlld.imageRecognition.modelEntity.RegressionBody;
|
||||
|
||||
public class XYBody {
|
||||
private double[] X;
|
||||
private double[] Y;
|
||||
private RegressionBody regressionBody;
|
||||
|
||||
public RegressionBody getRegressionBody() {
|
||||
return regressionBody;
|
||||
}
|
||||
|
||||
public void setRegressionBody(RegressionBody regressionBody) {
|
||||
this.regressionBody = regressionBody;
|
||||
}
|
||||
|
||||
public double[] getX() {
|
||||
return X;
|
||||
}
|
||||
|
||||
public void setX(double[] x) {
|
||||
X = x;
|
||||
}
|
||||
|
||||
public double[] getY() {
|
||||
return Y;
|
||||
}
|
||||
|
||||
public void setY(double[] y) {
|
||||
Y = y;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package org.wlld.imageRecognition.border;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class DistBody {
|
||||
private int id;//id
|
||||
private double dist;//距离
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getDist() {
|
||||
return dist;
|
||||
}
|
||||
|
||||
public void setDist(double dist) {
|
||||
this.dist = dist;
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package org.wlld.imageRecognition.border;
|
||||
|
||||
import org.wlld.MatrixTools.Matrix;
|
||||
import org.wlld.imageRecognition.MeanClustering;
|
||||
import org.wlld.imageRecognition.RGBNorm;
|
||||
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class GMClustering extends MeanClustering {
|
||||
private double regionSize;//单区域面积
|
||||
|
||||
public double getRegionSize() {
|
||||
return regionSize;
|
||||
}
|
||||
|
||||
public void setRegionSize(double regionSize) {
|
||||
this.regionSize = regionSize;
|
||||
}
|
||||
|
||||
public GMClustering(int speciesQuantity) throws Exception {
|
||||
super(speciesQuantity);
|
||||
}
|
||||
|
||||
public double getProbabilityDensity(double[] feature) throws Exception {//获取总概率密度
|
||||
double sigma = 0;
|
||||
for (RGBNorm rgbNorm : matrices) {
|
||||
sigma = sigma + rgbNorm.getGMProbability(feature);
|
||||
}
|
||||
return sigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
super.start();
|
||||
for (RGBNorm rgbNorm : matrices) {//高斯系数初始化
|
||||
rgbNorm.gm();
|
||||
}
|
||||
for (int i = 0; i < 50; i++) {
|
||||
gmClustering();
|
||||
}
|
||||
}
|
||||
|
||||
public void insertParameter(Matrix matrix) throws Exception {
|
||||
int y = matrix.getY();
|
||||
int size = y / speciesQuantity;
|
||||
for (int i = 0; i <= y - size; i += size) {
|
||||
double[] feature = new double[size];
|
||||
RGBNorm rgbNorm = new RGBNorm();
|
||||
matrices.add(rgbNorm);
|
||||
for (int j = i; j < i + size; j++) {
|
||||
feature[j - i] = matrix.getNumber(0, j);
|
||||
}
|
||||
rgbNorm.insertFeature(feature);
|
||||
}
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
for (RGBNorm rgbNorm : matrices) {//高斯系数初始化
|
||||
rgbNorm.clearRGB();
|
||||
}
|
||||
}
|
||||
|
||||
private void gmClustering() throws Exception {//进行gm聚类
|
||||
clear();
|
||||
for (double[] rgb : matrixList) {//遍历当前集合
|
||||
double allProbability = 0;//全概率
|
||||
double[] pro = new double[speciesQuantity];
|
||||
for (int i = 0; i < speciesQuantity; i++) {
|
||||
RGBNorm rgbNorm = matrices.get(i);
|
||||
double probability = rgbNorm.getGMProbability(rgb);
|
||||
//System.out.println("pro===" + probability);
|
||||
allProbability = allProbability + probability;
|
||||
pro[i] = probability;
|
||||
}
|
||||
//求每个簇的后验概率
|
||||
for (int i = 0; i < speciesQuantity; i++) {
|
||||
pro[i] = pro[i] / allProbability;
|
||||
}
|
||||
//判断概率最大的簇
|
||||
int index = 0;
|
||||
double max = 0;
|
||||
for (int i = 0; i < speciesQuantity; i++) {
|
||||
if (pro[i] > max) {
|
||||
max = pro[i];
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
//注入特征
|
||||
matrices.get(index).setGmFeature(rgb, pro[index]);
|
||||
}
|
||||
for (RGBNorm rgbNorm : matrices) {//高斯系数初始化
|
||||
rgbNorm.gm();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.wlld.imageRecognition.modelEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description 混合高斯切割区域
|
||||
*/
|
||||
public class GMBody {
|
||||
private int type;//类别
|
||||
private List<Integer> pixels = new ArrayList<>();
|
||||
private int pixelNub = 0;
|
||||
private int nub;
|
||||
|
||||
public int getNub() {
|
||||
return nub;
|
||||
}
|
||||
|
||||
public void setNub(int nub) {
|
||||
this.nub = nub;
|
||||
}
|
||||
|
||||
public GMBody(int type, int x, int y) {
|
||||
this.type = type;
|
||||
pixelNub++;
|
||||
pixels.add((x << 12) | y);
|
||||
}
|
||||
|
||||
public int getPixelNub() {
|
||||
return pixelNub;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
private boolean isAdjacent(int x, int y, int i, int j) {
|
||||
boolean adjacent = false;
|
||||
if (Math.abs(x - i) == 1 || Math.abs(y - j) == 1) {
|
||||
adjacent = true;
|
||||
}
|
||||
return adjacent;
|
||||
}
|
||||
|
||||
public boolean insertRgb(int x, int y, int type) {
|
||||
boolean isRight = false;
|
||||
if (this.type == type) {
|
||||
for (int pixel : pixels) {
|
||||
int i = (pixel >> 12) & 0xfff;
|
||||
int j = pixel & 0xfff;
|
||||
if (isAdjacent(x, y, i, j)) {//相邻
|
||||
isRight = true;
|
||||
pixelNub++;
|
||||
pixels.add((x << 12) | y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isRight;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package org.wlld.imageRecognition.modelEntity;
|
||||
|
||||
import org.wlld.imageRecognition.segmentation.DimensionMappingStudy;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class KeyMapping {
|
||||
private Set<Integer> keys;
|
||||
private DimensionMappingStudy dimensionMapping;
|
||||
|
||||
public Set<Integer> getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public void setKeys(Set<Integer> keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public DimensionMappingStudy getDimensionMapping() {
|
||||
return dimensionMapping;
|
||||
}
|
||||
|
||||
public void setDimensionMapping(DimensionMappingStudy dimensionMapping) {
|
||||
this.dimensionMapping = dimensionMapping;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package org.wlld.imageRecognition.modelEntity;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description 映射体
|
||||
*/
|
||||
public class MappingBody {
|
||||
private double[] feature;//特征
|
||||
private double mappingNub;//映射好的值
|
||||
|
||||
public MappingBody(double[] feature) {
|
||||
this.feature = feature;
|
||||
double sigma = 0;
|
||||
for (int i = 0; i < feature.length; i++) {
|
||||
sigma = sigma + Math.pow(feature[i], 2);
|
||||
}
|
||||
mappingNub = Math.sqrt(sigma);
|
||||
}
|
||||
|
||||
public double[] getFeature() {
|
||||
return feature;
|
||||
}
|
||||
|
||||
public double getMappingNub() {
|
||||
return mappingNub;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package org.wlld.imageRecognition.modelEntity;
|
||||
|
||||
import org.wlld.MatrixTools.Matrix;
|
||||
import org.wlld.i.OutBack;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class RgbBack implements OutBack {
|
||||
private int id = 0;
|
||||
private double out = -2;
|
||||
|
||||
public void clear() {
|
||||
out = -2;
|
||||
id = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBack(double out, int id, long eventId) {
|
||||
if (out > this.out) {
|
||||
this.out = out;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getBackMatrix(Matrix matrix, long eventId) {
|
||||
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package org.wlld.imageRecognition.segmentation;
|
||||
|
||||
import org.wlld.MatrixTools.Matrix;
|
||||
import org.wlld.i.PsoFunction;
|
||||
import org.wlld.imageRecognition.ThreeChannelMatrix;
|
||||
import org.wlld.tools.Frequency;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @DATA
|
||||
* @Author LiDaPeng
|
||||
* @Description
|
||||
*/
|
||||
public class ColorFunction extends Frequency implements PsoFunction {
|
||||
private Matrix matrixR;
|
||||
private Matrix matrixG;
|
||||
private Matrix matrixB;
|
||||
private Map<Integer, double[]> pixels = new HashMap<>();
|
||||
|
||||
public ColorFunction(ThreeChannelMatrix threeChannelMatrix) {
|
||||
matrixR = threeChannelMatrix.getMatrixR();
|
||||
matrixG = threeChannelMatrix.getMatrixG();
|
||||
matrixB = threeChannelMatrix.getMatrixB();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getResult(double[] parameter, int id) throws Exception {
|
||||
int x = (int) parameter[0];
|
||||
int y = (int) parameter[1];
|
||||
double[] rgb = new double[]{matrixR.getNumber(x, y) / 255, matrixG.getNumber(x, y) / 255,
|
||||
matrixB.getNumber(x, y) / 255};
|
||||
pixels.put(id, rgb);
|
||||
//计算当前方差
|
||||
return getDist();
|
||||
//return getRegression();
|
||||
}
|
||||
|
||||
private double getRegression() throws Exception {
|
||||
RgbRegression rgbRegression = new RgbRegression(pixels.size());
|
||||
for (Map.Entry<Integer, double[]> entry : pixels.entrySet()) {
|
||||
double[] rgb = entry.getValue();
|
||||
rgbRegression.insertRGB(rgb);
|
||||
}
|
||||
double sigma = 0;
|
||||
if (rgbRegression.regression()) {
|
||||
for (Map.Entry<Integer, double[]> entry : pixels.entrySet()) {
|
||||
double[] rgb = entry.getValue();
|
||||
sigma = sigma + rgbRegression.getDisError(rgb);
|
||||
}
|
||||
sigma = sigma / pixels.size();
|
||||
}
|
||||
return sigma;
|
||||
}
|
||||
|
||||
private double getDist() {//计算当前均方误差
|
||||
double[] r = new double[pixels.size()];
|
||||
double[] g = new double[pixels.size()];
|
||||
double[] b = new double[pixels.size()];
|
||||
for (Map.Entry<Integer, double[]> entry : pixels.entrySet()) {
|
||||
double[] rgb = entry.getValue();
|
||||
int key = entry.getKey();
|
||||
r[key] = rgb[0];
|
||||
g[key] = rgb[1];
|
||||
b[key] = rgb[2];
|
||||
}
|
||||
return dc(r) + dc(g) + dc(b);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue