OpenCV関数とC++を使用して2つの画像をつなぎ合わせました。現在、最終的な画像に大きな黒い部分が含まれているという問題に直面しています。
最終的な画像は、有効な部分を含む長方形である必要があります。私の画像は次のとおりです。
黒い部分を削除するにはどうすればよいですか?
OpenCV関数とC++を使用して2つの画像をつなぎ合わせました。現在、最終的な画像に大きな黒い部分が含まれているという問題に直面しています。
最終的な画像は、有効な部分を含む長方形である必要があります。私の画像は次のとおりです。
黒い部分を削除するにはどうすればよいですか?
mevatron
の答えは、完全な画像を保持しながら、黒い領域の量を最小限に抑える1つの方法です。
もう1つのオプションは、画像の一部も失う完全な黒い領域を削除することですが、結果として見栄えの良い長方形の画像になります。以下はPythonコードです。
ここでは、以下のように画像の3つの主要なコーナーがあります。
私はそれらの値をマークしました。(1,x2), (x1,1), (x3,y3)
。これは、画像が(1,1)から始まるという仮定に基づいています。
コード:
最初のステップはと同じmevatron
です。画像をぼかしてノイズを除去し、画像にしきい値を設定してから、輪郭を見つけます。
import cv2
import numpy as np
img = cv2.imread('office.jpg')
img = cv2.resize(img,(800,400))
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray,3)
ret,thresh = cv2.threshold(gray,1,255,0)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
次に、画像である最大の輪郭を見つけます。ノイズが発生した場合に備えて、ノイズを回避するためです(ほとんどの場合、ノイズは発生しません)。または、のメソッドを使用できますmevatron
。
max_area = -1
best_cnt = None
for cnt in contours:
area = cv2.contourArea(cnt)
if area > max_area:
max_area = area
best_cnt = cnt
次に、輪郭を近似して、見つかった輪郭値の不要なポイントを削除しますが、すべてのコーナー値は保持されます。
approx = cv2.approxPolyDP(best_cnt,0.01*cv2.arcLength(best_cnt,True),True)
今、私たちはコーナーを見つけます。
まず、(x3、y3)を見つけます。一番遠いポイントです。とてもx3*y3
大きくなります。したがって、すべてのポイントのペアの製品を見つけて、最大の製品を持つペアを選択します。
far = approx[np.product(approx,2).argmax()][0]
次へ(1、x2)。最初の要素が1で、次に2番目の要素が最大になるポイントです。
ymax = approx[approx[:,:,0]==1].max()
次へ(x1,1)。2番目の要素が1で、最初の要素が最大になるポイントです。
xmax = approx[approx[:,:,1]==1].max()
今、私たちは見つけますminimum values in (far.x,xmax) and (far.y, ymax)
x = min(far[0],xmax)
y = min(far[1],ymax)
(1,1)と(x、y)で長方形を描くと、次のような結果が得られます。
したがって、画像をトリミングして長方形の領域を修正します。
img2 = img[:y,:x].copy()
結果は次のとおりです。
See, the problem is that you lose some parts of the stitched image.
これは、 threshold、findContours、およびboundingRectを使用して実行できます。
だから、これはPythonインターフェースでこれを行う簡単なスクリプトです。
stitched = cv2.imread('stitched.jpg', 0)
(_, mask) = cv2.threshold(stitched, 1.0, 255.0, cv2.THRESH_BINARY);
# findContours destroys input
temp = mask.copy()
(contours, _) = cv2.findContours(temp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# sort contours by largest first (if there are more than one)
contours = sorted(contours, key=lambda contour:len(contour), reverse=True)
roi = cv2.boundingRect(contours[0])
# use the roi to select into the original 'stitched' image
stitched[roi[1]:roi[3], roi[0]:roi[2]]
最終的には次のようになります。
注:生の画像では並べ替えは必要ない場合がありますが、圧縮画像を使用すると、低いしきい値を使用すると圧縮アーティファクトが表示されるため、並べ替えで後処理しました。
お役に立てば幸いです。
アクティブな輪郭(バルーン/ヘビ)を使用して、黒い領域を正確に選択できます。デモはここにあります。アクティブな輪郭はOpenCVで利用できます。cvSnakeImageを確認してください。