cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

(OpenCV小ネタ)テンプレートマッチングの画像エッジ部分のウィンドウ切り出し方法

すごく簡単な問題のはずなのに、上手くやる方法が分からなくてちょっと悩んだので自分向けメモ。

テンプレートマッチングの窓を画像範囲いっぱいまで取りたいのに、メモリが確保されてないから窓の切り出しが面倒くさい、と思ったことありません?*1

f:id:cvl-robot:20140206231230p:plain図.目標座標にメモリが無い問題

f:id:cvl-robot:20140206231305p:plain図.安易な解決法(IF文で条件わけ)

 

f:id:cvl-robot:20140206231418p:plain図.今のところの解決案

Mat clipCopy(InputArray _src, int cx, int cy, int w, int h, bool flag_larged = false){

  Mat src = _src.getMat();

  Mat dst;

  Mat larged;

 

  if(cx<0||cy<0||src.cols<=cx||src.rows<=cy) return dst;

  if(!flag_larged){

    larged = Mat::zeros(Size(w+src.cols,h+src.rows), src.type());

    Rect roi_src(w/2,h/2,src.cols,src.rows);

    Mat larged_src = larged(roi_src);

    src.copyTo(larged_src);

  }

  else{

    larged = src;

  }

 

  Rect roi_dst(cx,cy,w,h);

  Mat larged_dst = larged(roi_dst);

  larged_dst.copyTo(dst);

 

#if _DEBUG

  rectangle(larged, roi_dst, Scalar(255,255,255));

  imshow("larged", larged);

  imshow("dst", dst);

  waitKey();

#endif

 

return dst;

}

 使い方

window = clipCopy(Image, cx, cy, ww, wh);

if(window.empty()) goto error;

x,yは窓に切り出したい入力画像上での中心座標。撮りうる値は入力画像上でとりうる範囲と同じ座標(0,0)~(cols,rows)まで。wwは窓の幅、whは窓の高さ。返り値に切り出した窓を渡し、範囲外が指定されていると空のまま返すので、空かどうかを判別しエラー処理をする。

 

*1:(多分、OpenCVではもっと便利な関数が用意されているのに違いないのだけれど、見つからない。。。誰か上手い方法を知っていたら教えてください。)