javacv提取图像指纹 直方图实现代码
时间: 2024-02-26 09:57:24 浏览: 114
下面是使用JavaCV提取图像指纹,使用直方图方法的示例代码:
```java
import static org.bytedeco.opencv.global.opencv_core.CV_32FC1;
import static org.bytedeco.opencv.global.opencv_core.CV_WHOLE_SEQ;
import static org.bytedeco.opencv.global.opencv_core.addWeighted;
import static org.bytedeco.opencv.global.opencv_core.cvConvertScale;
import static org.bytedeco.opencv.global.opencv_core.cvCreateHist;
import static org.bytedeco.opencv.global.opencv_core.cvCreateImage;
import static org.bytedeco.opencv.global.opencv_core.cvGetSize;
import static org.bytedeco.opencv.global.opencv_core.cvMinMaxLoc;
import static org.bytedeco.opencv.global.opencv_core.cvNormalize;
import static org.bytedeco.opencv.global.opencv_imgcodecs.CV_LOAD_IMAGE_GRAYSCALE;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
import static org.bytedeco.opencv.global.opencv_imgproc.CV_COMP_CHISQR;
import static org.bytedeco.opencv.global.opencv_imgproc.CV_HIST_ARRAY;
import static org.bytedeco.opencv.global.opencv_imgproc.CV_INTER_LINEAR;
import static org.bytedeco.opencv.global.opencv_imgproc.cvCalcHist;
import static org.bytedeco.opencv.global.opencv_imgproc.cvCompareHist;
import static org.bytedeco.opencv.global.opencv_imgproc.cvEqualizeHist;
import static org.bytedeco.opencv.global.opencv_imgproc.cvGetMinMaxHistValue;
import static org.bytedeco.opencv.global.opencv_imgproc.cvResize;
import static org.bytedeco.opencv.global.opencv_imgproc.cvSetHistBinRanges;
import static org.bytedeco.opencv.global.opencv_imgproc.cvSetImageROI;
import static org.bytedeco.opencv.global.opencv_imgproc.cvSplit;
import org.bytedeco.javacpp.FloatPointer;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.opencv.opencv_core.CvArr;
import org.bytedeco.opencv.opencv_core.CvHistogram;
import org.bytedeco.opencv.opencv_core.CvMat;
import org.bytedeco.opencv.opencv_core.CvSize;
import org.bytedeco.opencv.opencv_core.IplImage;
public class ImageFingerprint {
// 提取图像指纹
public static float[] extract(IplImage image) {
// 将图像转换为灰度图像
IplImage grayImage = cvCreateImage(cvGetSize(image), image.depth(), 1);
cvCvtColor(image, grayImage, CV_INTER_LINEAR);
// 直方图均衡化
cvEqualizeHist(grayImage, grayImage);
// 分离图像通道
IplImage imageR = cvCreateImage(cvGetSize(image), image.depth(), 1);
IplImage imageG = cvCreateImage(cvGetSize(image), image.depth(), 1);
IplImage imageB = cvCreateImage(cvGetSize(image), image.depth(), 1);
cvSplit(image, imageR, imageG, imageB, null);
// 计算RGB三个通道的直方图
int histSize = 256;
CvHistogram histR = cvCreateHist(1, new int[] { histSize }, CV_HIST_ARRAY);
CvHistogram histG = cvCreateHist(1, new int[] { histSize }, CV_HIST_ARRAY);
CvHistogram histB = cvCreateHist(1, new int[] { histSize }, CV_HIST_ARRAY);
cvCalcHist(new IplImage[] { imageR }, histR, 0, null);
cvCalcHist(new IplImage[] { imageG }, histG, 0, null);
cvCalcHist(new IplImage[] { imageB }, histB, 0, null);
// 归一化直方图
float minVal[] = new float[1];
float maxVal[] = new float[1];
FloatPointer minValPointer = new FloatPointer(minVal);
FloatPointer maxValPointer = new FloatPointer(maxVal);
cvGetMinMaxHistValue(histR, minValPointer, maxValPointer, null, null);
cvNormalize(histR, histR, 1, 0, CV_COMP_CHISQR);
cvGetMinMaxHistValue(histG, minValPointer, maxValPointer, null, null);
cvNormalize(histG, histG, 1, 0, CV_COMP_CHISQR);
cvGetMinMaxHistValue(histB, minValPointer, maxValPointer, null, null);
cvNormalize(histB, histB, 1, 0, CV_COMP_CHISQR);
// 合并三个通道的直方图
int dim = 3;
CvSize size = cvGetSize(image);
CvMat data = CvMat.create(size.height(), size.width(), CV_32FC1);
CvHistogram hist = cvCreateHist(dim, new int[] { histSize, histSize, histSize }, CV_HIST_ARRAY);
Pointer pointer = hist.bins();
int ptrOffset = 0;
for (int i = 0; i < histSize; i++) {
for (int j = 0; j < histSize; j++) {
for (int k = 0; k < histSize; k++) {
((FloatPointer) pointer).put(ptrOffset++, (float) (cvGetHistValue_3D(histR, i, j, k) * 0.33
+ cvGetHistValue_3D(histG, i, j, k) * 0.33 + cvGetHistValue_3D(histB, i, j, k) * 0.33));
}
}
}
cvSetHistBinRanges(hist, new FloatPointer(new float[] { 0, 256, 0, 256, 0, 256 }));
cvCalcHist(data, hist, 0, null);
// 归一化直方图
cvNormalize(hist, hist, 1, 0, CV_COMP_CHISQR);
// 提取特征向量
float[] featureVector = new float[histSize * histSize * histSize];
FloatPointer featureVectorPointer = new FloatPointer(featureVector);
cvGetHistValue_3D(hist, featureVectorPointer);
// 释放内存
grayImage.release();
imageR.release();
imageG.release();
imageB.release();
histR.release();
histG.release();
histB.release();
hist.release();
data.release();
return featureVector;
}
// 计算两张图像的相似度
public static float similarity(IplImage image1, IplImage image2) {
// 提取图像指纹
float[] featureVector1 = extract(image1);
float[] featureVector2 = extract(image2);
// 比较相似度
CvHistogram hist1 = cvCreateHist(1, new int[] { featureVector1.length }, CV_HIST_ARRAY);
CvHistogram hist2 = cvCreateHist(1, new int[] { featureVector2.length }, CV_HIST_ARRAY);
FloatPointer featureVector1Pointer = new FloatPointer(featureVector1);
FloatPointer featureVector2Pointer = new FloatPointer(featureVector2);
cvSetHistBinRanges(hist1, new FloatPointer(new float[] { 0, 1 }));
cvSetHistBinRanges(hist2, new FloatPointer(new float[] { 0, 1 }));
cvCalcHist(new Pointer[] { featureVector1Pointer }, hist1, 0, null);
cvCalcHist(new Pointer[] { featureVector2Pointer }, hist2, 0, null);
cvNormalize(hist1, hist1, 1, 0, CV_COMP_CHISQR);
cvNormalize(hist2, hist2, 1, 0, CV_COMP_CHISQR);
float similarity = (float) cvCompareHist(hist1, hist2, CV_COMP_CHISQR);
// 释放内存
hist1.release();
hist2.release();
return similarity;
}
public static void main(String[] args) {
IplImage image1 = imread("image1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
IplImage image2 = imread("image2.jpg", CV_LOAD_IMAGE_GRAYSCALE);
float similarity = similarity(image1, image2);
System.out.println("相似度:" + similarity);
}
}
```
这个示例代码中的extract()方法用于提取图像指纹,similarity()方法用于计算两张图像的相似度。
阅读全文