javacv提取图像指纹 直方图
时间: 2023-08-24 11:05:59 浏览: 244
JavaCV可以用来提取图像的指纹,其中一种方法是使用直方图。下面是提取图像指纹的基本步骤:
1. 加载图像:使用JavaCV中的cvLoadImage()函数加载图像。
2. 转换图像:将图像转换为灰度图像,使用JavaCV中的cvCvtColor()函数。
3. 计算直方图:使用JavaCV中的cvCalcHist()函数计算灰度直方图。
4. 归一化直方图:使用JavaCV中的cvNormalizeHist()函数将直方图归一化。
5. 提取特征向量:使用JavaCV中的cvGetHistValue()函数提取直方图中的特征向量。
6. 返回特征向量:将特征向量作为图像的指纹返回。
需要注意的是,直方图方法只是图像指纹提取的一种方法,还有其他方法可以使用,如局部二值模式(LBP)等。
相关问题
javacv提取图像指纹 直方图实现代码
下面是使用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()方法用于计算两张图像的相似度。
java直方图文件相似度比较 指纹提取存储 不用javacv
要实现指纹提取并进行存储,可以使用Java自带的图像处理库ImageIO来读取图像文件,并使用Java自带的数据分析库Apache Commons Math来计算直方图和指纹,并将指纹存储在文件中。
以下是一个示例代码:
```java
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.imageio.ImageIO;
import org.apache.commons.math3.stat.descriptive.moment.Mean;
import org.apache.commons.math3.stat.descriptive.summary.Sum;
public class FingerprintExtract {
public static void main(String[] args) throws IOException {
// 读取图像文件
BufferedImage img = ImageIO.read(new File("image.jpg"));
// 计算直方图
int[] hist = calcHistogram(img);
// 计算指纹
int[] fingerprint = calcFingerprint(hist);
// 存储指纹
saveFingerprint(fingerprint, "fingerprint.txt");
}
private static int[] calcHistogram(BufferedImage img) {
int[] hist = new int[256];
for (int y = 0; y < img.getHeight(); y++) {
for (int x = 0; x < img.getWidth(); x++) {
int pixel = img.getRGB(x, y);
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = pixel & 0xff;
int gray = (r + g + b) / 3;
hist[gray]++;
}
}
return hist;
}
private static int[] calcFingerprint(int[] hist) {
int[] fingerprint = new int[64];
double[] histNorm = normalize(hist);
for (int i = 0; i < fingerprint.length; i++) {
int start = i * 4;
double max = Double.NEGATIVE_INFINITY;
int maxIndex = -1;
for (int j = start; j < start + 4; j++) {
if (histNorm[j] > max) {
max = histNorm[j];
maxIndex = j;
}
}
fingerprint[i] = maxIndex;
}
return fingerprint;
}
private static double[] normalize(int[] hist) {
double[] histNorm = new double[hist.length];
int numPixels = hist.length;
Mean mean = new Mean();
double histMean = mean.evaluate(hist);
for (int i = 0; i < hist.length; i++) {
histNorm[i] = hist[i] / (double) numPixels - histMean;
}
return histNorm;
}
private static void saveFingerprint(int[] fingerprint, String filename) throws IOException {
PrintWriter writer = new PrintWriter(filename);
for (int i = 0; i < fingerprint.length; i++) {
writer.print(fingerprint[i]);
if (i < fingerprint.length - 1) {
writer.print(",");
}
}
writer.close();
}
}
```
该代码读取一个图像文件,计算它的直方图和指纹,并将指纹存储在文件中。其中,`calcHistogram`方法用于计算直方图,`calcFingerprint`方法用于计算指纹,`normalize`方法用于将直方图归一化,以便计算指纹。`saveFingerprint`方法用于将指纹存储在文件中。指纹用逗号分隔,并存储在一个文本文件中。
阅读全文