image_fingerprint.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. cv::Mat img(height, width, CV_8UC3);
  41. int cvLinesizes[1];
  42. cvLinesizes[0] = img.step1();
  43. SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height,
  44. AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  45. sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes);
  46. sws_freeContext(conversion);
  47. if (img.empty()) {
  48. printf("image is empty.");
  49. return NULL;
  50. }
  51. if (file) fprintf(file, "fingerprintFromFFAVFrame 2\n");
  52. printf( "fingerprintFromFFAVFrame 2\n");
  53. // std::string str = frame->pts + "";
  54. // imshow(str, img);
  55. int scale_width = 8, scale_height = 8;
  56. cv::Mat gray, res;
  57. if (file) fprintf(file, "fingerprintFromFFAVFrame 3\n");
  58. printf( "fingerprintFromFFAVFrame 3\n");
  59. //缩放成8x8大小灰度图
  60. resize(img, res, Size(scale_width, scale_height));
  61. img.release();
  62. if (file) fprintf(file, "fingerprintFromFFAVFrame 4\n");
  63. printf( "fingerprintFromFFAVFrame 4\n");
  64. cvtColor(res, gray, COLOR_BGR2GRAY);
  65. res.release();
  66. if (file) fprintf(file, "fingerprintFromFFAVFrame 5\n");
  67. printf( "fingerprintFromFFAVFrame 5\n");
  68. //获取灰度平均值
  69. cv::Mat mat_mean, mat_stddev;
  70. meanStdDev(gray, mat_mean, mat_stddev);//求灰度图像的均值、均方差
  71. double mn = 0;
  72. if (!mat_mean.empty()) {
  73. mn = mat_mean.at<double>(0, 0);
  74. } else {
  75. printf("灰度平均值 empty!\n");
  76. return -1;
  77. };
  78. if (file) fprintf(file, "fingerprintFromFFAVFrame 6\n");
  79. printf( "fingerprintFromFFAVFrame 6\n");
  80. if (gray.cols * gray.rows < scale_height * scale_width)return NULL;
  81. // //得到图像指纹值
  82. for (int i = 0; i < 8; i++) {
  83. for (int j = 0; j < 8; j++) {
  84. buf[i * 8 + j] = (gray.at<unsigned char>(i, j) > mn) ? 1 : 0;
  85. }
  86. }
  87. if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n");
  88. printf( "fingerprintFromFFAVFrame 7\n");
  89. gray.release();
  90. printf( "fingerprintFromFFAVFrame 8\n");
  91. return scale_width * scale_height;
  92. }
  93. int fingerprintFromFFAVFrameV2(FILE *file, AVFrame *frame, char buf[64]) {
  94. if (file) fprintf(file, "fingerprintFromFFAVFrame\n");
  95. if (!frame)return NULL;
  96. int width = frame->width;
  97. int height = frame->height;
  98. cv::Mat img(height, width, CV_8UC3);
  99. int cvLinesizes[1];
  100. cvLinesizes[0] = img.step1();
  101. SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height,
  102. AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  103. sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes);
  104. sws_freeContext(conversion);
  105. if (img.empty()) {
  106. printf("image is empty.");
  107. return NULL;
  108. }
  109. int scale_width = 8, scale_height = 8;
  110. cv::Mat gray, res;
  111. cvtColor(img, gray, COLOR_BGR2GRAY);
  112. //缩放成8x8大小灰度图
  113. resize(gray, gray, Size(scale_width, scale_height));
  114. //获取灰度平均值
  115. cv::Mat mat_mean, mat_stddev;
  116. meanStdDev(gray, mat_mean, mat_stddev);//求灰度图像的均值、均方差
  117. double mn = 0;
  118. if (!mat_mean.empty()) {
  119. mn = mat_mean.at<double>(0, 0);
  120. } else {
  121. printf("灰度平均值 empty!\n");
  122. return -1;
  123. };
  124. if (gray.cols * gray.rows < scale_height * scale_width)return NULL;
  125. // //得到图像指纹值
  126. for (int i = 0; i < 8; i++) {
  127. for (int j = 0; j < 8; j++) {
  128. buf[i * 8 + j] = (gray.at<unsigned char>(i, j) > mn) ? 1 : 0;
  129. }
  130. }
  131. if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n");
  132. return scale_width * scale_height;
  133. }
  134. float fingerprint_compare(const char *arr, const char *arr2, int len) {
  135. int size = len;
  136. int sim_sum = 0;
  137. for (int i = 0; i < size; ++i) {
  138. if (arr[i] == arr2[i])
  139. sim_sum++;
  140. }
  141. return sim_sum * 1.0 / size;
  142. }