当前位置:   article > 正文

使用c++ opencv实现图片去重_opencv重叠率高的图像清除c++

opencv重叠率高的图像清除c++
使用感知哈希方法,进行缩略图比较,来判断图像的相似度

先把目录下的所有图片都读取出来,再进行判断

优点:速度快

缺点:获取所有图像的指纹需要较多内存和时间来进行处理

  1. #include <iostream>
  2. #include <unistd.h>
  3. #include <dirent.h>
  4. #include <sys/stat.h>
  5. #include "opencv2/core/core.hpp"
  6. #include "opencv2/highgui/highgui.hpp"
  7. #include "opencv2/imgproc/imgproc.hpp"
  8. using namespace std;
  9. using namespace cv;
  10. //使用感知哈希算法进行图片去重
  11. //构建一个结构体,用于存储对应名称和要比较的内容
  12. typedef struct MatStruct{
  13. string name;
  14. unsigned char buf[64];
  15. MatStruct(){
  16. name = "";
  17. memset(buf, 0, 64);
  18. }
  19. MatStruct(const struct MatStruct &ms){
  20. name = ms.name;
  21. memset(buf, 0, 64);
  22. memcpy(buf, ms.buf, 64);
  23. }
  24. //重载比较函数
  25. bool operator<(const struct MatStruct &ms)const {
  26. return name < ms.name;
  27. }
  28. }MatStruct;
  29. int getdirimages(string path, std::vector<MatStruct> &images)
  30. {
  31. std::vector<MatStruct> tmpimages;
  32. DIR *dir;
  33. struct dirent *ptr;
  34. dir = opendir(path.c_str());
  35. while((ptr = readdir(dir)) != NULL) {
  36. if((strcmp(ptr->d_name,".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
  37. continue;
  38. }
  39. string fullname = path + "/" + ptr->d_name;
  40. Mat img = imread(fullname);
  41. if(img.empty()){
  42. continue;
  43. }
  44. MatStruct ms;
  45. ms.name = ptr->d_name;
  46. Mat gray, res;
  47. //缩放成8x8大小灰度图
  48. resize(img, res, Size(8,8));
  49. cvtColor(res, gray, CV_BGR2GRAY);
  50. //获取灰度平均值
  51. double mn = mean(gray)[0];
  52. //比较像素灰度,获取图像指纹
  53. for(int i = 0; i < 8; i++){
  54. for(int j = 0; j < 8; j++){
  55. ms.buf[i*8 + j] = (gray.at<unsigned char>(i,j) > mn) ? 1 : 0;
  56. }
  57. }
  58. cout << "get " << fullname << endl;
  59. tmpimages.push_back(ms);
  60. }
  61. closedir(dir);
  62. std::sort(tmpimages.begin(), tmpimages.end());
  63. tmpimages.swap(images);
  64. }
  65. int main(int argc, char* argv[])
  66. {
  67. if(argc <= 1){
  68. cout << argv[0] << " picpath" << endl;
  69. return -1;
  70. }
  71. struct stat st;
  72. if(stat(argv[1], &st) != 0 || (st.st_mode & S_IFDIR) != S_IFDIR){
  73. cout << argv[1] << " is not dir" << endl;
  74. return -1;
  75. }
  76. int startpos = 0;
  77. int curpos = 0;
  78. std::vector<MatStruct> images;
  79. cout << "start getdir" << endl;
  80. getdirimages(argv[1], images);
  81. cout << "start compare" << endl;
  82. std::vector<MatStruct>::iterator it1 = images.begin();
  83. while(it1 != images.end()){
  84. std::vector<MatStruct>::iterator it2 = it1;
  85. curpos = 0;
  86. //存储需要删除的迭代对象
  87. std::vector<std::vector<MatStruct>::iterator> delImages;
  88. cout << it1->name << endl;
  89. while(it2 != images.end()){
  90. int diff = 0;
  91. if(it2 == it1){
  92. it2++;
  93. continue;
  94. }
  95. //比较两个图片的相似度,不同的地方不超过5,则为相似的图片
  96. for(int i = 0; i < 64; i++){
  97. if(it1->buf[i] != it2->buf[i]){
  98. diff++;
  99. }
  100. }
  101. if(diff < 5){
  102. delImages.push_back(it2);
  103. }
  104. it2++;
  105. }
  106. if(delImages.size() > 0){
  107. //删除图像
  108. for(int i = 0; i < delImages.size(); i++){
  109. cout << "remove " << delImages[i]->name << endl;
  110. string fullpath = string(argv[1]) + "/" + delImages[i]->name;
  111. unlink(fullpath.c_str());
  112. images.erase(delImages[i]);
  113. }
  114. it1 = images.begin();
  115. for(int index = 0; index < startpos; index++)
  116. it1++;
  117. continue;
  118. }
  119. startpos++;
  120. it1++;
  121. }
  122. return 0;
  123. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/81314
推荐阅读
相关标签
  

闽ICP备14008679号