当前位置:   article > 正文

OpenCV进行图像相似度对比的几种办法

opencv图像对比

转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/43853435
来自:shiter编写程序的艺术


这里写图片描述

对计算图像相似度的方法,本文做了如下总结,主要有三种办法:


1.PSNR峰值信噪比

PSNR(Peak Signal to Noise Ratio),一种全参考的图像质量评价指标。

简介:https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio

PSNR是最普遍和使用最为广泛的一种图像客观评价指标,然而它是基于对应像素点间的误差,即基于误差敏感的图像质量评价。由于并未考虑到人眼的视觉特性(人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高,人眼对一个区域的感知结果会受到其周围邻近区域的影响等),因而经常出现评价结果与人的主观感觉不一致的情况。

SSIM(structural similarity)结构相似性,也是一种全参考的图像质量评价指标,它分别从亮度、对比度、结构三方面度量图像相似性。

这里写图片描述

SSIM取值范围[0,1],值越大,表示图像失真越小.

在实际应用中,可以利用滑动窗将图像分块,令分块总数为N,考虑到窗口形状对分块的影响,采用高斯加权计算每一窗口的均值、方差以及协方差,然后计算对应块的结构相似度SSIM,最后将平均值作为两图像的结构相似性度量,即平均结构相似性MSSIM:


参考资料

[1] 峰值信噪比-维基百科

[2] 王宇庆,刘维亚,王勇. 一种基于局部方差和结构相似度的图像质量评价方法[J]. 光电子激光,2008。
[3]http://www.cnblogs.com/vincent2012/archive/2012/10/13/2723152.html

官方文档的说明,不过是GPU版本的,我们可以修改不用gpu不然还得重新编译

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/highgui/video-input-psnr-ssim/video-input-psnr-ssim.html#videoinputpsnrmssim
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.html?highlight=psnr


  1. // PSNR.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <iostream> // Console I/O
  5. #include <sstream> // String to number conversion
  6. #include <opencv2/core/core.hpp> // Basic OpenCV structures
  7. #include <opencv2/imgproc/imgproc.hpp>// Image processing methods for the CPU
  8. #include <opencv2/highgui/highgui.hpp>// Read images
  9. #include <opencv2/gpu/gpu.hpp> // GPU structures and methods
  10. using namespace std;
  11. using namespace cv;
  12. double getPSNR(const Mat& I1, const Mat& I2); // CPU versions
  13. Scalar getMSSIM( const Mat& I1, const Mat& I2);
  14. double getPSNR_GPU(const Mat& I1, const Mat& I2); // Basic GPU versions
  15. Scalar getMSSIM_GPU( const Mat& I1, const Mat& I2);
  16. struct BufferPSNR // Optimized GPU versions
  17. { // Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.
  18. gpu::GpuMat gI1, gI2, gs, t1,t2;
  19. gpu::GpuMat buf;
  20. };
  21. double getPSNR_GPU_optimized(const Mat& I1, const Mat& I2, BufferPSNR& b);
  22. struct BufferMSSIM // Optimized GPU versions
  23. { // Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.
  24. gpu::GpuMat gI1, gI2, gs, t1,t2;
  25. gpu::GpuMat I1_2, I2_2, I1_I2;
  26. vector<gpu::GpuMat> vI1, vI2;
  27. gpu::GpuMat mu1, mu2;
  28. gpu::GpuMat mu1_2, mu2_2, mu1_mu2;
  29. gpu::GpuMat sigma1_2, sigma2_2, sigma12;
  30. gpu::GpuMat t3;
  31. gpu::GpuMat ssim_map;
  32. gpu::GpuMat buf;
  33. };
  34. Scalar getMSSIM_GPU_optimized( const Mat& i1, const Mat& i2, BufferMSSIM& b);
  35. void help()
  36. {
  37. cout
  38. << "\n--------------------------------------------------------------------------" << endl
  39. << "This program shows how to port your CPU code to GPU or write that from scratch." << endl
  40. << "You can see the performance improvement for the similarity check methods (PSNR and SSIM)." << endl
  41. << "Usage:" << endl
  42. << "./gpu-basics-similarity referenceImage comparedImage numberOfTimesToRunTest(like 10)." << endl
  43. << "--------------------------------------------------------------------------" << endl
  44. << endl;
  45. }
  46. int main(int argc, char *argv[])
  47. {
  48. help();
  49. Mat I1 = imread("swan1.jpg",1); // Read the two images
  50. Mat I2 = imread("swan2.jpg",1);
  51. if (!I1.data || !I2.data) // Check for success
  52. {
  53. cout << "Couldn't read the image";
  54. return 0;
  55. }
  56. BufferPSNR bufferPSNR;
  57. BufferMSSIM bufferMSSIM;
  58. int TIMES;
  59. stringstream sstr("500");
  60. sstr >> TIMES;
  61. double time, result;
  62. //------------------------------- PSNR CPU ----------------------------------------------------
  63. time = (double)getTickCount();
  64. for (int i = 0; i < TIMES; ++i)
  65. result = getPSNR(I1,I2);
  66. time = 1000*((double)getTickCount() - time)/getTickFrequency();
  67. time /= TIMES;
  68. cout << "Time of PSNR CPU (averaged for " << TIMES << " runs): " << time << " milliseconds."
  69. << " With result of: " << result << endl;
  70. ------------------------------- PSNR GPU ----------------------------------------------------
  71. //time = (double)getTickCount();
  72. //for (int i = 0; i < TIMES; ++i)
  73. // result = getPSNR_GPU(I1,I2);
  74. //time = 1000*((double)getTickCount() - time)/getTickFrequency();
  75. //time /= TIMES;
  76. //cout << "Time of PSNR GPU (averaged for " << TIMES << " runs): " << time << " milliseconds."
  77. // << " With result of: " << result << endl;
  78. /*
  79. //------------------------------- PSNR GPU Optimized--------------------------------------------
  80. time = (double)getTickCount(); // Initial call
  81. result = getPSNR_GPU_optimized(I1, I2, bufferPSNR);
  82. time = 1000*((double)getTickCount() - time)/getTickFrequency();
  83. cout << "Initial call GPU optimized: " << time <<" milliseconds."
  84. << " With result of: " << result << endl;
  85. time = (double)getTickCount();
  86. for (int i = 0; i < TIMES; ++i)
  87. result = getPSNR_GPU_optimized(I1, I2, bufferPSNR);
  88. time = 1000*((double)getTickCount() - time)/getTickFrequency();
  89. time /= TIMES;
  90. cout << "Time of PSNR GPU OPTIMIZED ( / " << TIMES << " runs): &
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/287708
推荐阅读
相关标签
  

闽ICP备14008679号