image_fingerprint.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. if (!frame)return NULL;
  37. // if (1) {
  38. // memset((void *)buf, 0,sizeof(char) * 8 * 8);
  39. // for (int i = 0; i <64 ; ++i) {
  40. // buf[i] = 1;
  41. // }
  42. // return 64;
  43. // }
  44. // auto img = avframeToCvmat(frame);
  45. int width = frame->width;
  46. int height = frame->height;
  47. cv::Mat img(height, width, CV_8UC3);
  48. int cvLinesizes[1];
  49. cvLinesizes[0] = img.step1();
  50. SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height,
  51. AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  52. sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes);
  53. sws_freeContext(conversion);
  54. if (img.empty()) {
  55. printf("image is empty.");
  56. return NULL;
  57. }
  58. if (file) fprintf(file, "fingerprintFromFFAVFrame 2\n");
  59. // std::string str = frame->pts + "";
  60. // imshow(str, img);
  61. int scale_width = 8, scale_height = 8;
  62. Mat gray, res;
  63. if (file) fprintf(file, "fingerprintFromFFAVFrame 3\n");
  64. //缩放成8x8大小灰度图
  65. resize(img, res, Size(scale_width, scale_height));
  66. if (file) fprintf(file, "fingerprintFromFFAVFrame 4\n");
  67. cvtColor(res, gray, COLOR_BGR2GRAY);
  68. if (file) fprintf(file, "fingerprintFromFFAVFrame 5\n");
  69. 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. //获取灰度平均值
  79. // mn = mean(gray)[0];
  80. if (file) fprintf(file, "fingerprintFromFFAVFrame 6\n");
  81. if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n");
  82. if (gray.cols * gray.rows < scale_height * scale_width)return NULL;
  83. // //得到图像指纹值
  84. for (int i = 0; i < 8; i++) {
  85. for (int j = 0; j < 8; j++) {
  86. buf[i * 8 + j] = (gray.at<unsigned char>(i, j) > mn) ? 1 : 0;
  87. }
  88. }
  89. if (file) fprintf(file, "fingerprintFromFFAVFrame 8\n");
  90. if (file) fprintf(file, "fingerprintFromFFAVFrame 9\n");
  91. return scale_width * scale_height;
  92. }
  93. float fingerprint_compare(const char *arr, const char *arr2, int len) {
  94. int size = len;
  95. int sim_sum = 0;
  96. for (int i = 0; i < size; ++i) {
  97. if (arr[i] == arr2[i])
  98. sim_sum++;
  99. }
  100. return sim_sum * 1.0 / size;
  101. }