Opencv实现纵横比保持的图像缩放
生活随笔
收集整理的這篇文章主要介紹了
Opencv实现纵横比保持的图像缩放
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前實現過C實現縱橫比保持的RGB圖像縮放,其實計算效率是不高的。
opencv的好多實現都是自帶mmx, sse加速的。所以就來研究一下如何用opencv來實現縱橫比保持的圖像縮放。
查看了一下opencv resize函數的詳細定義:
resize函數
函數原型:
void cv::resize( InputArray _src, OutputArray _dst, Size dsize, double inv_scale_x = 0, double inv_scale_y = 0, int interpolation = INTER_LINEAR )參數說明:
-
src,輸入圖像,Mat類型即可;
-
dst,輸出圖像,當其非零時,有著dsize(第三個參數)的尺寸或者有src.size()計算出來;
-
dsize,輸出圖像的大小。如果它等于0,由下式計算:
dsize = Size( round(fx*src.cols, round(fy*src.rows))); 其中fx,fy,dsize都能不為0 -
fx,沿水平軸的縮放系數,默認值為0,且等于0時,由下式計算:
inv_scale_x = (double)dsize.width/ssize.width; -
fy,沿垂直軸的縮放系數,默認值為0,且等于0時,由下式計算:
inv_scale_y = (double)dsize.height/ssize.height; -
interpolation,用于指定插值方式,默認值為INTER_LINEAR(線性插值),可選插值方式如下:
| INTER_NEAREST | 最近鄰插值 |
| INTER_LINEAR | 線性插值(默認值) |
| INTER_AREA | 區域插值(利用像素區域關系的重采樣插值) |
| INTER_CUBIC | 三次樣條插值(超過4×4像素領域內的雙三次插值) |
| INTER_LANCZOS4 | Lanczos插值(超過8×8像素鄰域的Lanczos插值) |
注意:要縮小圖像,一般情況下用INTER_AREA來插值;而若要放大圖像,一般情況下用INTER_CUBIC(效率不高,不推薦)或INTER_LINEAR(效率高,推薦)
但是該函數實現不了任意尺寸的縱橫比保持的圖像縮放。
仔細想了一下,可以先做crop操作,然后再縮放,分兩步,這樣就可以達到縱橫比保持的圖像縮放。
代碼如下:
#include "opencv2/opencv.hpp" #include "opencv2/opencv.hpp" #include<fstream> #include <chrono>using namespace std; using namespace cv;int main(int, char**) {cv::Size szSize(3840 , 2160);uchar *b_Buffer = new uchar[szSize.width * szSize.height * 2];uchar *rgb_Buffer = new uchar[szSize.width * szSize.height * 3];string binFile("input.yuv");ifstream File_VideoFile;File_VideoFile.open(binFile, ios::in | ios::binary);if (!File_VideoFile.is_open()){std::cerr << "[ERROR] cannot open the YUV Input File " << binFile << endl;std::cerr << std::endl;assert(0);}File_VideoFile.read((char*)b_Buffer, sizeof(uchar)*szSize.width*szSize.height*2);File_VideoFile.close();cv::Mat mSrc(szSize,CV_8UC2, b_Buffer);cv::Mat mSrc_BGR(szSize, CV_8UC3);auto time1 = std::chrono::steady_clock::now();cvtColor(mSrc, mSrc_BGR, COLOR_YUV2BGR_YUYV);auto time2 = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::microseconds>(time2-time1).count();printf("cv time: %.2f ms.\n", (float)duration / 1000);Size dstSize(1600, 1600);Size srcSize(3840, 2160);Mat dst_img(dstSize, CV_8UC3);//crop firstdouble fx = dstSize.width / srcSize.width;double fy = dstSize.height / srcSize.height;int xmin = 0, xmax = 0;int ymin = 0, ymax = 0;if (fx > fy) {//crop yxmin = 0;xmax = srcSize.width;ymin = (srcSize.height - srcSize.width) >> 1;ymax = srcSize.height - ymin;} else {//crop xymin = 0;ymax = srcSize.height;xmin = (srcSize.width - srcSize.height) >> 1;xmax = srcSize.width - xmin;}Mat crop_img = mSrc_BGR(Range(ymin, ymax), Range(xmin, xmax));//scale secondresize(crop_img, dst_img, dstSize);imwrite( "dst.bmp", dst_img);imwrite( "rgb24.bmp", mSrc_BGR);delete[] b_Buffer;delete[] rgb_Buffer;return 0; }總結
以上是生活随笔為你收集整理的Opencv实现纵横比保持的图像缩放的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: marquee 和JS 滚动效果
- 下一篇: 什么是用户故事及用户故事在敏捷开发中如何