Android中的OpenCV图像比较
[编辑] 我设计了一些图像比较代码。匹配的部分仍然有点缺陷,我希望得到一些帮助。该项目可在- 我有两张图像Img1和Img2: 当我在openCV中使用以下命令时Android中的OpenCV图像比较,android,opencv,feature-detection,surf,image-comparison,Android,Opencv,Feature Detection,Surf,Image Comparison,[编辑] 我设计了一些图像比较代码。匹配的部分仍然有点缺陷,我希望得到一些帮助。该项目可在- 我有两张图像Img1和Img2: 当我在openCV中使用以下命令时 Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg"); Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg"); try{ double l2_norm = Core.norm( img1, img2
Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
try{
double l2_norm = Core.norm( img1, img2 );
tv.setText(l2_norm+"");
} catch(Exception e) {
//image is not a duplicate
}
我得到l2_范数的一个双值。此双精度值因重复图像对而异。但如果图像不同,则会引发异常。这就是我识别重复图像的方法吗?还是有更好的方法?我在谷歌上搜索了很多遍,没有找到一个真正令人信服的答案。我想知道如何比较两幅图像并根据图像得到true
或false
的布尔值的代码和说明
编辑
我已经试过了,但是if
条件从未满足过。我假设存在一些差异,但是对于标量
,没有比较
函数。我该怎么办
编辑
这种方法又有缺陷。虽然它可以用来比较图像,精度相当高,但当图像大小不同时,它就失败了
当图像大小不同且我打印标量值时,我得到以下结果:
[9768383.0,1.0052889E7,1.0381814E7,0.0][1.5897384E7,1.6322252E7,1.690251E7,0.0]
第二个数字和第三个数字之间的差异虽然不大,但与比较相同大小的图像时的差异相当大。然而,第一个数字变化最大
比较两幅图像内容的最快方法是什么
[编辑]
我正在使用我找到的代码
我不知道如何初始化MatOfKeyPoint
变量keypoints
和logoKeypoints
。以下是我的代码片段:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
//FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST);
//Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2RGB);
//Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2RGB);
DescriptorExtractor SurfExtractor = DescriptorExtractor
.create(DescriptorExtractor.SURF);
//extract keypoints
MatOfKeyPoint keypoints, logoKeypoints;
long time= System.currentTimeMillis();
detector.detect(img1, keypoints);
Log.d("LOG!", "number of query Keypoints= " + keypoints.size());
detector.detect(img2, logoKeypoints);
Log.d("LOG!", "number of logo Keypoints= " + logoKeypoints.size());
Log.d("LOG!", "keypoint calculation time elapsed" + (System.currentTimeMillis() -time));
//Descript keypoints
long time2 = System.currentTimeMillis();
Mat descriptors = new Mat();
Mat logoDescriptors = new Mat();
Log.d("LOG!", "logo type" + img2.type() + " intype" + img1.type());
SurfExtractor.compute(img1, keypoints, descriptors);
SurfExtractor.compute(img2, logoKeypoints, logoDescriptors);
Log.d("LOG!", "Description time elapsed" + (System.currentTimeMillis()- time2));
显然,我无法将变量
关键点
和logoKeypoints
初始化为null,因为我将收到null指针异常。如何初始化它们?使用cv2.absDiff
计算图片之间的差异,使用cv2.sumElems
计算所有像素差异之和
然后发明一个阈值来判断两幅图像是否相似。你应该明白这不是一个简单的问题,你可以遵循不同的概念。我将只指出两个没有源代码的解决方案
要匹配,请使用原因,您需要SURF或SIFT的欧几里德距离。您可以尝试以下代码:
Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
Mat result = new Mat();
Core.compare(img1,img2,result,Core.CMP_NE);
int val = Core.countNonZero(result);
if(val == 0) {
//Duplicate Image
} else {
//Different Image
}
在这里,代码比较函数将比较两个图像,如果图像之间存在不相似性,则特定矩阵值将为255,所有其他值将为零。然后可以计算非零值的数量,以确定图像是否相等。这只适用于完全相同的图像
如果要比较忽略灯光效果的图像,我建议您先生成边缘图像(使用OpenCV的canny函数),然后比较图像
希望这个答案能帮助你 本OpenCV教程希望提供有关该主题的一些信息。试抓和其他的不一样!如果抛出异常(catch block),则会出现完全错误的情况@卫星D-我知道。这就是为什么我问是否有更好的方法。我不相信你需要,MatofKeypoints,logoKeypoints;很好。方法检测器。检测(img1,关键点);然后将使用找到的特征填充关键点。否则,请尝试MatofKeypoints=new MatOfKeyPoint()@Emile你能为图像关键点比较提供正确的代码吗?你能解释一下吗?我必须为absDiff设置一个阈值。所以,这是有缺陷的。或者您可以告诉我最安全的阈值是什么?首先,很抱歉您必须使用cv.sum,因为sumelems似乎只是python。其次,需要sum返回值的阈值!您可以将其包装在一个方法中,该方法根据sum的返回值返回true或false
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
//FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST);
//Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2RGB);
//Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2RGB);
DescriptorExtractor SurfExtractor = DescriptorExtractor
.create(DescriptorExtractor.SURF);
//extract keypoints
MatOfKeyPoint keypoints, logoKeypoints;
long time= System.currentTimeMillis();
detector.detect(img1, keypoints);
Log.d("LOG!", "number of query Keypoints= " + keypoints.size());
detector.detect(img2, logoKeypoints);
Log.d("LOG!", "number of logo Keypoints= " + logoKeypoints.size());
Log.d("LOG!", "keypoint calculation time elapsed" + (System.currentTimeMillis() -time));
//Descript keypoints
long time2 = System.currentTimeMillis();
Mat descriptors = new Mat();
Mat logoDescriptors = new Mat();
Log.d("LOG!", "logo type" + img2.type() + " intype" + img1.type());
SurfExtractor.compute(img1, keypoints, descriptors);
SurfExtractor.compute(img2, logoKeypoints, logoDescriptors);
Log.d("LOG!", "Description time elapsed" + (System.currentTimeMillis()- time2));
MatOfKeyPoint reference = new MatOfKeyPoint(matOfReferenceImage);
Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
Mat result = new Mat();
Core.compare(img1,img2,result,Core.CMP_NE);
int val = Core.countNonZero(result);
if(val == 0) {
//Duplicate Image
} else {
//Different Image
}