OpenCV画像スケーリングresize各種補間方式の比較が実現された。


1.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.まとめ
    テスト結果の表示:
  •  スピード比較:INTERNEAREST(近隣内挿)>INTER_LINE EAR(線形補間)>INTER_CUBIC(三次スプライン補間)>INTER_AREA  (エリア補間)
  • 画像を縮小する場合は、波紋が出ないように、INTER_を推奨します。AREA 領域補間法
  • OpenCVおすすめ:画像を縮小するには、一般的に、钾INTER_を使用することを推奨します。AREA補間の効果が一番いいです。画像を拡大するには、しばしばINTER_uを使います。CUBIC(速度は遅いですが、効果は一番いいです)、またはINTERを使用します。LINE(スピードが速いし、効果もいいです。)最近の隣人補間についてはINTER_NEARESTは、一般的に推奨されていません。
  • ここで、OpenCV画像スケーリングresizeの様々な補間方式についての比較的実現された文章を紹介します。OpenCV画像スケーリングresizeの内容については、以前の記事を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。