// // Created by 阳坤 on 2022/3/2. // #include "image_fingerprint.h" //AVFrame 转 cv::mat cv::Mat avframeToCvmat(const AVFrame *frame) { int width = frame->width; int height = frame->height; cv::Mat image(height, width, CV_8UC3); int cvLinesizes[1]; cvLinesizes[0] = image.step1(); SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height, AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL); sws_scale(conversion, frame->data, frame->linesize, 0, height, &image.data, cvLinesizes); sws_freeContext(conversion); return image; } //cv::Mat 转 AVFrame AVFrame *cvmatToAvframe(cv::Mat *image, AVFrame *frame) { int width = image->cols; int height = image->rows; int cvLinesizes[1]; cvLinesizes[0] = image->step1(); if (frame == NULL) { frame = av_frame_alloc(); av_image_alloc(frame->data, frame->linesize, width, height, AVPixelFormat::AV_PIX_FMT_YUV420P, 1); } SwsContext *conversion = sws_getContext(width, height, AVPixelFormat::AV_PIX_FMT_BGR24, width, height, (AVPixelFormat) frame->format, SWS_FAST_BILINEAR, NULL, NULL, NULL); sws_scale(conversion, &image->data, cvLinesizes, 0, height, frame->data, frame->linesize); sws_freeContext(conversion); return frame; } int fingerprintFromFFAVFrame(FILE *file, AVFrame *frame, char buf[64]) { if (file) fprintf(file, "fingerprintFromFFAVFrame\n"); printf("fingerprintFromFFAVFrame\n"); if (!frame || frame->width <= 0 || frame->height <= 0)return NULL; int width = frame->width; int height = frame->height; cv::Mat img(height, width, CV_8UC3); int cvLinesizes[1]; cvLinesizes[0] = img.step1(); SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height, AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL); sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes); sws_freeContext(conversion); if (img.empty()) { printf("image is empty."); return NULL; } if (file) fprintf(file, "fingerprintFromFFAVFrame 2\n"); printf( "fingerprintFromFFAVFrame 2\n"); // std::string str = frame->pts + ""; // imshow(str, img); int scale_width = 8, scale_height = 8; cv::Mat gray, res; if (file) fprintf(file, "fingerprintFromFFAVFrame 3\n"); printf( "fingerprintFromFFAVFrame 3\n"); //缩放成8x8大小灰度图 resize(img, res, Size(scale_width, scale_height)); img.release(); if (file) fprintf(file, "fingerprintFromFFAVFrame 4\n"); printf( "fingerprintFromFFAVFrame 4\n"); cvtColor(res, gray, COLOR_BGR2GRAY); res.release(); if (file) fprintf(file, "fingerprintFromFFAVFrame 5\n"); printf( "fingerprintFromFFAVFrame 5\n"); //获取灰度平均值 cv::Mat mat_mean, mat_stddev; meanStdDev(gray, mat_mean, mat_stddev);//求灰度图像的均值、均方差 double mn = 0; if (!mat_mean.empty()) { mn = mat_mean.at(0, 0); } else { printf("灰度平均值 empty!\n"); return -1; }; if (file) fprintf(file, "fingerprintFromFFAVFrame 6\n"); printf( "fingerprintFromFFAVFrame 6\n"); if (gray.cols * gray.rows < scale_height * scale_width)return NULL; // //得到图像指纹值 for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { buf[i * 8 + j] = (gray.at(i, j) > mn) ? 1 : 0; } } if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n"); printf( "fingerprintFromFFAVFrame 7\n"); gray.release(); printf( "fingerprintFromFFAVFrame 8\n"); return scale_width * scale_height; } int fingerprintFromFFAVFrameV2(FILE *file, AVFrame *frame, char buf[64]) { if (file) fprintf(file, "fingerprintFromFFAVFrame\n"); if (!frame)return NULL; int width = frame->width; int height = frame->height; cv::Mat img(height, width, CV_8UC3); int cvLinesizes[1]; cvLinesizes[0] = img.step1(); SwsContext *conversion = sws_getContext(width, height, (AVPixelFormat) frame->format, width, height, AVPixelFormat::AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL); sws_scale(conversion, frame->data, frame->linesize, 0, height, &img.data, cvLinesizes); sws_freeContext(conversion); if (img.empty()) { printf("image is empty."); return NULL; } int scale_width = 8, scale_height = 8; cv::Mat gray, res; cvtColor(img, gray, COLOR_BGR2GRAY); //缩放成8x8大小灰度图 resize(gray, gray, Size(scale_width, scale_height)); //获取灰度平均值 cv::Mat mat_mean, mat_stddev; meanStdDev(gray, mat_mean, mat_stddev);//求灰度图像的均值、均方差 double mn = 0; if (!mat_mean.empty()) { mn = mat_mean.at(0, 0); } else { printf("灰度平均值 empty!\n"); return -1; }; if (gray.cols * gray.rows < scale_height * scale_width)return NULL; // //得到图像指纹值 for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { buf[i * 8 + j] = (gray.at(i, j) > mn) ? 1 : 0; } } if (file) fprintf(file, "fingerprintFromFFAVFrame 7\n"); return scale_width * scale_height; } float fingerprint_compare(const char *arr, const char *arr2, int len) { int size = len; int sim_sum = 0; for (int i = 0; i < size; ++i) { if (arr[i] == arr2[i]) sim_sum++; } return sim_sum * 1.0 / size; }