image_fingerprint.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //
  2. // Created by 阳坤 on 2022/3/2.
  3. //
  4. #include "image_fingerprint.h"
  5. //AVFrame 转 cv::mat
  6. cv::Mat avframeToCvmat(const AVFrame *frame) {
  7. int width = frame->width;
  8. int height = frame->height;
  9. cv::Mat image(height, width, CV_8UC3);
  10. int cvLinesizes[1];
  11. cvLinesizes[0] = image.step1();
  12. SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height,
  13. AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  14. sws_scale(conversion, frame->data, frame->linesize, 0, height, &image.data, cvLinesizes);
  15. sws_freeContext(conversion);
  16. return image;
  17. }
  18. //cv::Mat 转 AVFrame
  19. AVFrame *cvmatToAvframe(cv::Mat *image, AVFrame *frame) {
  20. int width = image->cols;
  21. int height = image->rows;
  22. int cvLinesizes[1];
  23. cvLinesizes[0] = image->step1();
  24. if (frame == NULL) {
  25. frame = av_frame_alloc();
  26. av_image_alloc(frame->data, frame->linesize, width, height, AVPixelFormat::AV_PIX_FMT_YUV420P, 1);
  27. }
  28. SwsContext *conversion = sws_getContext(width, height, AVPixelFormat::AV_PIX_FMT_BGR24, width, height,
  29. (AVPixelFormat) frame->format, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  30. sws_scale(conversion, &image->data, cvLinesizes, 0, height, frame->data, frame->linesize);
  31. sws_freeContext(conversion);
  32. return frame;
  33. }
  34. int fingerprintFromFFAVFrame(FILE *file, AVFrame *frame, char buf[64]) {
  35. if (file) fprintf(file, "fingerprintFromFFAVFrame\n");
  36. printf("fingerprintFromFFAVFrame\n");
  37. if (!frame || frame->width <= 0 || frame->height <= 0)return NULL;
  38. int width = frame->width;
  39. int height = frame->height;
  40. printf("fingerprintFromFFAVFrame -1\n");
  41. cv::Mat img(height, width, CV_8UC3);
  42. printf("fingerprintFromFFAVFrame -2\n");
  43. int cvLinesizes[1];
  44. cvLinesizes[0] = img.step1();
  45. printf("fingerprintFromFFAVFrame -3\n");
  46. SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height,
  47. AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  48. if (conversion){
  49. printf("fingerprintFromFFAVFrame -4\n");
  50. sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes);
  51. printf("fingerprintFromFFAVFrame -5\n");
  52. sws_freeContext(conversion);
  53. conversion = NULL;
  54. } else {
  55. printf("sws_getContext init error .");
  56. return NULL;
  57. }
  58. printf("fingerprintFromFFAVFrame -6\n");
  59. if (img.empty()) {
  60. printf("image is empty.");
  61. return NULL;
  62. }
  63. if (file) fprintf(file, "fingerprintFromFFAVFrame 2\n");
  64. printf( "fingerprintFromFFAVFrame 2\n");
  65. // std::string str = frame->pts + "";
  66. // imshow(str, img);
  67. int scale_width = 8, scale_height = 8;
  68. cv::Mat gray, res;
  69. if (file) fprintf(file, "fingerprintFromFFAVFrame 3\n");
  70. printf( "fingerprintFromFFAVFrame 3\n");
  71. //缩放成8x8大小灰度图
  72. resize(img, res, Size(scale_width, scale_height));
  73. img.release();
  74. if (file) fprintf(file, "fingerprintFromFFAVFrame 4\n");
  75. printf( "fingerprintFromFFAVFrame 4\n");
  76. cvtColor(res, gray, COLOR_BGR2GRAY);
  77. res.release();
  78. if (file) fprintf(file, "fingerprintFromFFAVFrame 5\n");
  79. printf( "fingerprintFromFFAVFrame 5\n");
  80. //获取灰度平均值
  81. cv::Mat mat_mean, mat_stddev;
  82. meanStdDev(gray, mat_mean, mat_stddev);//求灰度图像的均值、均方差
  83. double mn = 0;
  84. if (!mat_mean.empty()) {
  85. mn = mat_mean.at<double>(0, 0);
  86. } else {
  87. printf("灰度平均值 empty!\n");
  88. return -1;
  89. };
  90. if (file) fprintf(file, "fingerprintFromFFAVFrame 6\n");
  91. printf( "fingerprintFromFFAVFrame 6\n");
  92. if (gray.cols * gray.rows < scale_height * scale_width)return NULL;
  93. // //得到图像指纹值
  94. for (int i = 0; i < 8; i++) {
  95. for (int j = 0; j < 8; j++) {
  96. buf[i * 8 + j] = (gray.at<unsigned char>(i, j) > mn) ? 1 : 0;
  97. }
  98. }
  99. if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n");
  100. printf( "fingerprintFromFFAVFrame 7\n");
  101. gray.release();
  102. printf( "fingerprintFromFFAVFrame 8\n");
  103. return scale_width * scale_height;
  104. }
  105. int fingerprintFromFFAVFrameV2(FILE *file, AVFrame *frame, char buf[64]) {
  106. if (file) fprintf(file, "fingerprintFromFFAVFrame\n");
  107. if (!frame)return NULL;
  108. int width = frame->width;
  109. int height = frame->height;
  110. cv::Mat img(height, width, CV_8UC3);
  111. int cvLinesizes[1];
  112. cvLinesizes[0] = img.step1();
  113. SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height,
  114. AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  115. sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes);
  116. sws_freeContext(conversion);
  117. if (img.empty()) {
  118. printf("image is empty.");
  119. return NULL;
  120. }
  121. int scale_width = 8, scale_height = 8;
  122. cv::Mat gray, res;
  123. cvtColor(img, gray, COLOR_BGR2GRAY);
  124. //缩放成8x8大小灰度图
  125. resize(gray, gray, Size(scale_width, scale_height));
  126. //获取灰度平均值
  127. cv::Mat mat_mean, mat_stddev;
  128. meanStdDev(gray, mat_mean, mat_stddev);//求灰度图像的均值、均方差
  129. double mn = 0;
  130. if (!mat_mean.empty()) {
  131. mn = mat_mean.at<double>(0, 0);
  132. } else {
  133. printf("灰度平均值 empty!\n");
  134. return -1;
  135. };
  136. if (gray.cols * gray.rows < scale_height * scale_width)return NULL;
  137. // //得到图像指纹值
  138. for (int i = 0; i < 8; i++) {
  139. for (int j = 0; j < 8; j++) {
  140. buf[i * 8 + j] = (gray.at<unsigned char>(i, j) > mn) ? 1 : 0;
  141. }
  142. }
  143. if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n");
  144. return scale_width * scale_height;
  145. }
  146. float fingerprint_compare(const char *arr, const char *arr2, int len) {
  147. int size = len;
  148. int sim_sum = 0;
  149. for (int i = 0; i < size; ++i) {
  150. if (arr[i] == arr2[i])
  151. sim_sum++;
  152. }
  153. return sim_sum * 1.0 / size;
  154. }