OpenCV画像スケーリングresize各種補間方式の比較が実現された。
1.resize関数説明
OpenCVは、画像のサイズを変更するためにresize関数を提供します。関数のプロトタイプは以下の通りです。
src:入力して、元の画像、すなわちサイズを変更する画像。dst:出力、サイズを変えた後の画像、この画像は元の画像と同じ内容を持っていますが、大きさが元の画像と違っています。dsize:出力画像のサイズ。このパラメータが0でない場合、元の画像をこのSize(width,height)で指定したサイズにスケールすることを表します。このパラメータが0の場合、元の画像のサイズは次の数式で計算されます。
dsize=Size(round(fx*src.com)、round(fy*src.rows)
ここで、fxとfyとは、以下に述べる2つのパラメータであり、画像width方向とheight方向のズーム比である。
fx:width方向のスケーリング比率は、0であれば、dsize.width/src.comによって計算されます。fy:height方向のスケーリング比率は0なら、dsize.height/src.rowsによって計算されます。interpolation:これは補間の方式を指定します。画像をスケーリングした後、必ずピクセルを再計算します。このパラメータによってピクセルを再計算する方法を指定します。次の種類があります。
INTER.NEAREST - 最近接補間
INTER.LINE - 双線形補間は、最後のパラメータが指定されていない場合、デフォルトではこの方法を使用します。
INTER.AREA -エリア補間reampling using pixel relation.It may be a preferred method for image decimation,as it gives moire'-free reresult.But when the mage is zoomed,it is simiar to the INTER.NEAREST method.
INTER.CUBIC - 4 x 4ピクセル近傍の双立方補間
INTER.LANCZ OST 4 - 8 x 8ピクセル近傍のLanczos補間
使用上の注意事項:
dsizeとfx/fyは同時に0になりません。あるいはdsizeの値を指定して、fxとfyを空白にして、そのままデフォルトの値を使います。
OpenCV公式説明:赤いブロックに注意すると、その話:https://docs.opencv.org/3.2.0/da/d54/group__イムプロtranform.菵ガ47 a 974309 e 9102 f 08 231 edc 7 e 7529 d
To shrink anイメージ、it will general lookベストwith cv:INTER_AREA interpolation、whers to enlarge anイメージ、it will general look best with cv:INTER_CUBIC or cv:INTER_LINE (faster but still look OK)
2.各種補間方式の比較
OpenCVのcv:resize関数は様々な補間方式をサポートしています。ここでは主に以下の4つの一般的な補間方式を比較します。
参考資料:「OpenCVにおけるresize関数5つの補間アルゴリズムの実現過程」
2.1 INTER_NEAREST(最近傍間)
最近の傍間は最も簡単な補間方法であり、目と目に近い点を新たな挿入点として選択し、計算式は以下の通りである。
補間後のエッジ効果:最近の点を新たな挿入点とするので、エッジに緩やかな漸遅的な過度領域が現れず、拡大画像に鋸歯状の現象が発生しやすい。
2.2 INTERUCUBIC (三次スプライン補間)
補間後のエッジ効果:鋸歯の発生を効果的に避けることができます。
2.3 INTER_LINE EAR(線形補間)
線形補間は距離を重みとする内挿法である。
補間後のエッジ効果:鋸歯の発生を効果的に避けることができます。
2.4 INTERUAREA (領域補間)
領域補間は3つの場合に分けられますが、画像の拡大は2つの線形補間に似ています。画像の縮小(x軸、y軸同時縮小)は2つの場合に分けられます。したがって画像を縮小する場合は、波紋を避けるために、領域補間法を採用することを推奨します。
OpenGLの説明文書にはこう説明されています。To shrink anイメージ、it will generaally look best with嗵INTER啯AREA interpolation、wheres to enlarge anイメージ、it will generaally look best with嗵INTER呸CUBIC(slow)or〹INTERLINE EAR(faster but still look OK)。
画像を縮小するなら、INTERUを使うのがおすすめです。AREA補間の効果が一番いいです。画像を拡大するには、しばしばINTER_uを使います。CUBIC(速度は遅いですが、効果は一番いいです)、またはINTERを使用します。LINE(スピードが速いし、効果もいいです。)
補間後のエッジ効果:
テストコード:
image input size:1000 x 1000
レスゼイメージ:900 x 900、INTERYNEAREST:0.3 89 ms
レスゼイメージ:900 x 900、INTERYLINE:0.65 ms
レスゼイメージ:900 x 900、INTERYAREA :2.611 ms
レスゼイメージ:900 x 900、INTERYCUBIC :1.320 ms
3.まとめ
テスト結果の表示: スピード比較:INTERNEAREST(近隣内挿)>INTER_LINE EAR(線形補間)>INTER_CUBIC(三次スプライン補間)>INTER_AREA (エリア補間) 画像を縮小する場合は、波紋が出ないように、INTER_を推奨します。AREA 領域補間法 OpenCVおすすめ:画像を縮小するには、一般的に、钾INTER_を使用することを推奨します。AREA補間の効果が一番いいです。画像を拡大するには、しばしばINTER_uを使います。CUBIC(速度は遅いですが、効果は一番いいです)、またはINTERを使用します。LINE(スピードが速いし、効果もいいです。)最近の隣人補間についてはINTER_NEARESTは、一般的に推奨されていません。
ここで、OpenCV画像スケーリングresizeの様々な補間方式についての比較的実現された文章を紹介します。OpenCV画像スケーリングresizeの内容については、以前の記事を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。
OpenCVは、画像のサイズを変更するためにresize関数を提供します。関数のプロトタイプは以下の通りです。
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );
パラメータの説明:src:入力して、元の画像、すなわちサイズを変更する画像。dst:出力、サイズを変えた後の画像、この画像は元の画像と同じ内容を持っていますが、大きさが元の画像と違っています。dsize:出力画像のサイズ。このパラメータが0でない場合、元の画像をこのSize(width,height)で指定したサイズにスケールすることを表します。このパラメータが0の場合、元の画像のサイズは次の数式で計算されます。
dsize=Size(round(fx*src.com)、round(fy*src.rows)
ここで、fxとfyとは、以下に述べる2つのパラメータであり、画像width方向とheight方向のズーム比である。
fx:width方向のスケーリング比率は、0であれば、dsize.width/src.comによって計算されます。fy:height方向のスケーリング比率は0なら、dsize.height/src.rowsによって計算されます。interpolation:これは補間の方式を指定します。画像をスケーリングした後、必ずピクセルを再計算します。このパラメータによってピクセルを再計算する方法を指定します。次の種類があります。
INTER.NEAREST - 最近接補間
INTER.LINE - 双線形補間は、最後のパラメータが指定されていない場合、デフォルトではこの方法を使用します。
INTER.AREA -エリア補間reampling using pixel relation.It may be a preferred method for image decimation,as it gives moire'-free reresult.But when the mage is zoomed,it is simiar to the INTER.NEAREST method.
INTER.CUBIC - 4 x 4ピクセル近傍の双立方補間
INTER.LANCZ OST 4 - 8 x 8ピクセル近傍のLanczos補間
使用上の注意事項:
dsizeとfx/fyは同時に0になりません。あるいはdsizeの値を指定して、fxとfyを空白にして、そのままデフォルトの値を使います。
resize(img, imgDst, Size(30,30));
あるいはdsizeを0にして、fxとfyの値を指定してください。fx=fy=0.5なら、原図の二つの方向を倍に縮小するのと同じです。OpenCV公式説明:赤いブロックに注意すると、その話:https://docs.opencv.org/3.2.0/da/d54/group__イムプロtranform.菵ガ47 a 974309 e 9102 f 08 231 edc 7 e 7529 d
To shrink anイメージ、it will general lookベストwith cv:INTER_AREA interpolation、whers to enlarge anイメージ、it will general look best with cv:INTER_CUBIC or cv:INTER_LINE (faster but still look OK)
2.各種補間方式の比較
OpenCVのcv:resize関数は様々な補間方式をサポートしています。ここでは主に以下の4つの一般的な補間方式を比較します。
参考資料:「OpenCVにおけるresize関数5つの補間アルゴリズムの実現過程」
2.1 INTER_NEAREST(最近傍間)
最近の傍間は最も簡単な補間方法であり、目と目に近い点を新たな挿入点として選択し、計算式は以下の通りである。
補間後のエッジ効果:最近の点を新たな挿入点とするので、エッジに緩やかな漸遅的な過度領域が現れず、拡大画像に鋸歯状の現象が発生しやすい。
2.2 INTERUCUBIC (三次スプライン補間)
補間後のエッジ効果:鋸歯の発生を効果的に避けることができます。
2.3 INTER_LINE EAR(線形補間)
線形補間は距離を重みとする内挿法である。
補間後のエッジ効果:鋸歯の発生を効果的に避けることができます。
2.4 INTERUAREA (領域補間)
領域補間は3つの場合に分けられますが、画像の拡大は2つの線形補間に似ています。画像の縮小(x軸、y軸同時縮小)は2つの場合に分けられます。したがって画像を縮小する場合は、波紋を避けるために、領域補間法を採用することを推奨します。
OpenGLの説明文書にはこう説明されています。To shrink anイメージ、it will generaally look best with嗵INTER啯AREA interpolation、wheres to enlarge anイメージ、it will generaally look best with嗵INTER呸CUBIC(slow)or〹INTERLINE EAR(faster but still look OK)。
画像を縮小するなら、INTERUを使うのがおすすめです。AREA補間の効果が一番いいです。画像を拡大するには、しばしばINTER_uを使います。CUBIC(速度は遅いですが、効果は一番いいです)、またはINTERを使用します。LINE(スピードが速いし、効果もいいです。)
補間後のエッジ効果:
テストコード:
#include <chrono>
#include <opencv2/opencv.hpp>
#define millisecond 1000000
#define DEBUG_PRINT(...) printf( __VA_ARGS__); printf("
")
#define DEBUG_TIME(time_) auto time_ =std::chrono::high_resolution_clock::now()
#define RUN_TIME(time_) (double)(time_).count()/millisecond
using namespace std;
cv::Mat image_resize(cv::Mat image, int width, int height, int interpolation, int num) {
cv::Mat dest;
for (int i = 0; i < num; ++i) {
cv::resize(image, dest, cv::Size(width, height), 0, 0, interpolation);//
}
return dest;
}
int main() {
string path = "../1.jpg";
cv::Mat image = cv::imread(path);
cv::resize(image, image, cv::Size(1000, 1000));
int re_width = 900;
int re_height = 900;
int num=10;
cv::Mat image2X_INTER_NEAREST;
cv::Mat image2X_INTER_LINEAR;
cv::Mat image2X_INTER_AREA;
cv::Mat image2X_INTER_CUBIC;
cv::Mat initMat;
DEBUG_PRINT("image input size:%dx%d", image.rows, image.cols);
DEBUG_TIME(T0);
image2X_INTER_NEAREST=image_resize(image, re_width, re_height, cv::INTER_NEAREST, num);
DEBUG_TIME(T1);
image2X_INTER_LINEAR=image_resize(image, re_width, re_height, cv::INTER_LINEAR, num);
DEBUG_TIME(T2);
image2X_INTER_AREA=image_resize(image, re_width, re_height, cv::INTER_AREA, num);
DEBUG_TIME(T3);
image2X_INTER_CUBIC=image_resize(image, re_width, re_height, cv::INTER_CUBIC, num);
DEBUG_TIME(T4);
DEBUG_PRINT("resize_image:%dx%d,INTER_NEAREST:%3.3fms",
image2X_INTER_NEAREST.rows,
image2X_INTER_NEAREST.cols,
RUN_TIME(T1 - T0)/num);
DEBUG_PRINT("resize_image:%dx%d,INTER_LINEAR :%3.3fms",
image2X_INTER_LINEAR.rows,
image2X_INTER_LINEAR.cols,
RUN_TIME(T2 - T1)/num);
DEBUG_PRINT("resize_image:%dx%d,INTER_AREA :%3.3fms",
image2X_INTER_AREA.rows,
image2X_INTER_AREA.cols,
RUN_TIME(T3 - T2)/num);
DEBUG_PRINT("resize_image:%dx%d,INTER_CUBIC :%3.3fms",
image2X_INTER_CUBIC.rows,
image2X_INTER_CUBIC.cols,
RUN_TIME(T4 - T3)/num);
return 0;
}
実行結果:image input size:1000 x 1000
レスゼイメージ:900 x 900、INTERYNEAREST:0.3 89 ms
レスゼイメージ:900 x 900、INTERYLINE:0.65 ms
レスゼイメージ:900 x 900、INTERYAREA :2.611 ms
レスゼイメージ:900 x 900、INTERYCUBIC :1.320 ms
3.まとめ
テスト結果の表示: