memcpy函数实现_等比例缩放c++ opencv 实现
生活随笔
收集整理的這篇文章主要介紹了
memcpy函数实现_等比例缩放c++ opencv 实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景:在目標檢測算法中, 輸入圖片等比例resize時mAP比直接resize會高幾個點。
實現:使用c++ 和opencv實現(之所以沒用python,是因為用于生產環境)
先貼代碼:
#include <math.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream>using namespace cv;struct object_rect {int x;int y;int width;int height; };int resize_uniform(Mat &src, Mat &dst, Size dst_size, object_rect &effect_area) {int w = src.cols;int h = src.rows;int dst_w = dst_size.width;int dst_h = dst_size.height;std::cout << "src: (" << h << ", " << w << ")" << std::endl;dst = Mat(Size(dst_w, dst_h), CV_8UC3, Scalar(0));float ratio_src = w*1.0 / h;float ratio_dst = dst_w*1.0 / dst_h;int tmp_w=0;int tmp_h=0;if (ratio_src > ratio_dst) {tmp_w = dst_w;tmp_h = floor((dst_w*1.0 / w) * h);} else if (ratio_src < ratio_dst){tmp_h = dst_h;tmp_w = floor((dst_h*1.0 / h) * w);} else {resize(src, dst, dst_size);effect_area.x = 0;effect_area.y = 0;effect_area.width = dst_w;effect_area.height = dst_h;return 0;}std::cout << "tmp: (" << tmp_h << ", " << tmp_w << ")" << std::endl;Mat tmp;resize(src, tmp, Size(tmp_w, tmp_h));if (tmp_w != dst_w) { //高對齊,寬沒對齊int index_w = floor((dst_w - tmp_w) / 2.0);std::cout << "index_w: " << index_w << std::endl;for (int i=0; i<dst_h; i++) {memcpy(dst.data+i*dst_w*3 + index_w*3, tmp.data+i*tmp_w*3, tmp_w*3);}effect_area.x = index_w;effect_area.y = 0;effect_area.width = tmp_w;effect_area.height = tmp_h;} else if (tmp_h != dst_h) { //寬對齊, 高沒有對齊int index_h = floor((dst_h - tmp_h) / 2.0);std::cout << "index_h: " << index_h << std::endl;memcpy(dst.data+index_h*dst_w*3, tmp.data, tmp_w*tmp_h*3);effect_area.x = 0;effect_area.y = index_h;effect_area.width = tmp_w;effect_area.height = tmp_h;} else {printf("errorn");}return 0; }int crop_effect_area(Mat &uniform_scaled, Mat &dst, Size ori_size, object_rect effect_area) {Mat tmp = Mat(Size(effect_area.width, effect_area.height), CV_8UC3, Scalar(0));if(effect_area.x == 0 && effect_area.y == 0) {resize(uniform_scaled, dst, ori_size);return 0;} else if (effect_area.x == 0) {memcpy(tmp.data, uniform_scaled.data+effect_area.y*effect_area.width*3, effect_area.width*effect_area.height*3);} else if (effect_area.y == 0) {for (int i=0; i<effect_area.height; i++) {memcpy(tmp.data + i*effect_area.width*3, uniform_scaled.data+i*uniform_scaled.cols*3+effect_area.x*3, effect_area.width*3);}}resize(tmp, dst, ori_size);return 0; }int main() {Mat img = imread("test.jpg", 3);Mat dst;object_rect res_area;(void)resize_uniform(img, dst, Size(608, 608), res_area);imwrite("out.jpg", dst);std::cout << "effectiave area: (" << res_area.x << ", " << res_area.y << ", " << res_area.width << ", " << res_area.height << ")" << std::endl;Mat out = imread("out.jpg", 3);Mat recov;crop_effect_area(out, recov, Size(img.cols, img.rows), res_area);imwrite("recov.jpg", recov);return 0; }其中就兩個函數:
1.等比例縮放函數:
intresize_uniform函數,輸入原始src圖像, 輸入目的resize大小dst_size, 輸出等比例resize圖像dst, 以及等比例縮放后圖像的有效區域effect_area(有效區域的左上角和長寬),下圖分別是原始圖像和resize_uniform函數處理后的dst圖像:
原始圖像: 333*500等比例縮放后的圖像:608*608, 有效區域:(x:0, y:102, w:608, h:404)2. 等比例恢復函數:
int crop_effect_area(Mat &uniform_scaled, Mat &dst, Size ori_size, object_rect effect_area)crop_effect_area函數輸入等比例縮放后的圖像uniform_scaled, 以及等比例縮放之前的原始圖像大小ori_size, 等比例縮放后的有效區域effect_area, 輸出為crop掉等比例縮放后的圖像的黑邊,然后resize到原始圖像大小。
恢復后的圖總結
以上是生活随笔為你收集整理的memcpy函数实现_等比例缩放c++ opencv 实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【先生】丘成桐:中国人可以做世界一流学者
- 下一篇: 【文末福利】图论算法:稳定婚姻问题,如何