OpenCV的resize函式優化

2021-09-26 15:48:37 字數 2502 閱讀 9434

在使用opencv做影象處理的時候,最常見的問題是c++版本效能不足,以resize函式為例來說明,將size為[864,1323,3]的函式縮小一半:

mat img0;

gettimeofday(&t4, null);

cv::resize(source, img0, cv::size(cols_out,rows_out));

gettimeofday(&t5, null);

time = 1000*(t5.tv_sec - t4.tv_sec) + (double)(t5.tv_usec - t4.tv_usec)/1000;

printf("frank cv::resize = %lf\n", time);

output:

frank cv::resize = 13.569000(ms) on macmini(2.6 ghz intel core i5)

需要13ms才能完成這個操作,對於一半應用的實時性要求,要再33ms內處理一幀,超過1/3的時間花在resize上,是非常不合理的。

針對上面這種1/2大小的resize,可以這樣來思考,既然我已經知道輸出mat的長寬是輸入mat的一半,那麼輸出mat的每個畫素值都是從原圖的4個畫素得到的乙個對映,事實上opencv也是用類似的技巧,從原圖的點對映到輸出影象的畫素點,這個對映可以是nearest neiborhood,也可以是雙線性插值、平均、取左上角等等。對於一般自然影象,我們可以直接使用nn對映來獲得輸出影象的點。

使用上面的方法:

double time = 0.0;

gettimeofday(&t1, null);

mat half_img = resizebyhalf(source, &lefttopint4);

int wh = half_img.cols;

int hh = half_img.rows;

printf("half_img = %d, %d\n", hh, wh);

gettimeofday(&t2, null);

time = 1000*(t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec)/1000;

printf("frank resizebyhalf = %lf\n", time);

output:frank resizebyhalf = 10.539000

時間相比opencv的版本,縮小了3ms

如果我們不是resize到1/2等特定的長寬,而且任意尺寸呢?上面的方法就不能直接使用,但是這個思想是可以借鑑的,我們可以進一步將最臨近演算法發揮的更好,對outuput的每個點,先根據長寬比計算其在原圖中最鄰近的畫素點,然後直接根據最鄰近的思想,直接拷貝channel個位元組作為輸出影象:

mat new_img = mat(rows_out, cols_out, cv_8uc3);

resizebynn(source.data, new_img.data, source.rows, source.cols, source.channels(), new_img.rows, new_img.cols);

gettimeofday(&t4, null);

time = 1000*(t4.tv_sec - t3.tv_sec) + (double)(t4.tv_usec - t3.tv_usec)/1000;

printf("frank resizebynn = %lf\n", time);

output: frank resizebynn = 6.738000

時間已經縮小到原先的一半!還有乙個殺招,待日後更新。。。。

原圖:

resizebynn的結果:

resizebyhalf

uchar maxint4(uchar x0, uchar x1, uchar x2, uchar x3)

uchar meanint4(uchar x0, uchar x1, uchar x2, uchar x3)

uchar lefttopint4(uchar x0, uchar x1, uchar x2, uchar x3)

mat resizebyhalf(mat input, uchar (*pfun)(uchar x0, uchar x1, uchar x2, uchar x3))}}

return output;

}

resizebynn
void resizebynn(uchar *input, uchar *output, int height_in, int width_in, int channels, int height_out, int width_out)

}return;

}

多謝閱讀!

Opencv 尺寸調整(resize)

影象的尺寸調整,如放大或者縮小影象,我們可以用到cv2.resize函式,該函式可以將原影象精準的轉換為目標影象大小。python dst cv.resize src,dsize dst fx fy interpolation src 輸入影象,源影象 dst 輸出影象,當dsize!0時,大小為d...

opencv學習筆記之resize

前邊一篇說opencv中縮放僅有仿射變換一種,查證才知道是錯的,opencv中也有類似matlab中的imresize的函式,即是c 版的resize 當然還有影象金字塔方法 其原型為void resize inputarray src,outputarray dst,size dsize,doub...

opencv 幾何變換之resize

引數說明 1.src 原圖 2.dst 目標影象。3.當引數dsize不為0時,dst的大小為size 否則,它的大小需要根據src的大小,縮放因子 引數fx和fy決定。4.dst的型別 type 和src影象相同。5.引數dsize和引數 fx,fy 不能夠同時為0。6.dsize和縮放因子同時存...