The example in this article describes how to implement similar image recognition based on histogram application in Java, which is a very practical technique. Share it with everyone for your reference. The specific analysis is as follows:
1. Algorithm Overview:
First, collect histogram data of the source image and the image to be filtered, normalize the collected image histograms, and then use the Babbitt coefficient algorithm to calculate the histogram data, and finally obtain the image similarity value, and its value range between [0, 1]
0 means extremely different, 1 means extremely similar (same).
2. Detailed explanation of algorithm steps:
It can be roughly divided into two steps. Based on the pixel data of the source image and the candidate image, the respective histogram data is generated. Step 2: Use the histogram result output from the first step and use the Bhattacharyya coefficient algorithm to calculate the similarity value.
Step 1: Histogram calculation
Histograms are divided into grayscale histograms and RGB histograms. The calculation of the grayscale image histogram is very simple. Just initialize a histogram array H with a size of 256, and then complete frequency distribution statistics based on the pixel value. Assume that the pixel value is 124. Then H[124] += 1, For color RGB pixels, there are two ways to express histograms. One is a single histogram, and the other is a three-dimensional histogram. The three-dimensional histogram is relatively simple and clear. It corresponds to the three colors of RGB and defines three histograms. HR, HG, HB, assuming that the RGB value of a certain pixel point P is (4, 231,129), then the histogram calculation is HR[4] += 1, HG[231] += 1, HB[129] += 1, after completing statistics for each pixel, RGB color histogram data is generated.
The single histogram SH of RGB pixels is slightly more complicated. The value range of each color is between 0 and 255. It is assumed that it can be divided into equal parts in a certain range. When there are 8 equal parts, the value range of each equal part When it is 32 and 16 equal parts, the value range of each equal part is 16. When it is 4 equal parts, the range of each equal part value is 64. Assume that the RGB value is (14, 68, 221), After 16 equal parts, its corresponding histogram index values are: (0, 4, 13), according to the formula for calculating the index value: index = R + G*16 + B*16*16
The corresponding histogram index = 0 + 4*16 + 13 * 16 * 16, SH[3392] += 1
In this way, all RGB pixel values are traversed to complete the histogram data calculation.
Step 2: Calculate the Babbitt coefficient. The calculation formula is as follows:
Among them, P and P' represent the source and candidate image histogram data respectively. The square roots of the products of each data point with the same i are added together.
The result is the image similarity value (Batch coefficient factor value), which ranges from 0 to 1.
The program effect is shown in the figure below:
The similarity is over 99%, extremely similar
Similarity: 72%, generally similar
3. The program histogram calculation source code is as follows:
public void setGreenBinCount(int greenBinCount) { this.greenBins = greenBinCount; } public void setBlueBinCount(int blueBinCount) { this.blueBins = blueBinCount; } public float[] filter(BufferedImage src, BufferedImage dest) { int width = src.getWidth( ); int height = src.getHeight(); int[] inPixels = new int[width*height]; float[] histogramData = new float[redBins * greenBins * blueBins]; getRGB( src, 0, 0, width, height, inPixels ); int index = 0; int redIdx = 0, greenIdx = 0, blueIdx = 0; int singleIndex = 0; float total = 0; for(int row=0; row<height; row++) { int ta = 0, tr = 0, tg = 0, tb = 0; for(int col=0; col<width; col++) { index = row * width + col; ta = (inPixels[index] >> 24) & 0xff; tr = (inPixels[index] >> 16) & 0xff; tg = (inPixels[index] >> 8) & 0xff; tb = inPixels[index] & 0xff; redIdx = (int)getBinIndex(redBins, tr, 255); greenIdx = (int)getBinIndex(greenBins, tg, 255); blueIdx = (int)getBinIndex(blueBins, tb, 255); singleIndex = redIdx + greenIdx * redBins + blueIdx * redBins * greenBins; histogramData[singleIndex] += 1; total += 1; } } // start to normalize the histogram data for (int i = 0; i < histogramData .length; i++) { histogramData[i] = histogramData[i] / total; } return histogramData; }The code to calculate the Bath coefficient is as follows:
/** * Bhattacharyya Coefficient * http://www.cse.yorku.ca/~kosta/CompVis_Notes/bhattacharyya.pdf * * @return */ public double modelMatch() { HistogramFilter hfilter = new HistogramFilter(); float[] sourceData = hfilter.filter(sourceImage, null); float[] candidateData = hfilter.filter(candidateImage, null); double[] mixedData = new double[sourceData.length]; for(int i=0; i<sourceData.length; i++ ) { mixedData[i] = Math.sqrt(sourceData[i] * candidateData[i] ); } // The values of Bhattacharyya Coefficient ranges from 0 to 1, double similarity = 0; for(int i=0; i<mixedData.length; i++ ) { similarity += mixedData[i]; } // The degree of similarity return similarity; }I hope this article will be helpful to everyone’s Java programming.