2012-05-17 33 views
10

私は、OpenCV関数とC++を使って2つの画像を一緒に縫い合わせました。今私は、最終的な画像に大きな黒い部分が含まれているという問題に直面しています。画像から黒い部分を削除するには?

最終イメージは有効部分を含む矩形である必要があります。 私のイメージは以下の通りです:

enter image description here

どのように私は黒の部分を削除することができますか?

+0

... – LiMuBei

+2

画像を追加しながら、その結果を 'imwrite'を使って出力し、それを追加します。あなたの質問に答えた人は、画像から不要な領域を削除する必要があるため、スクリーンショットを追加するよりも優れています。 –

+4

あなたのワークスペースはきれいです。 – wengseng

答えて

16

mevatronフルイメージを保持しながら黒領域の量を最小限に抑える方法です。

もう一つの選択肢は完全な黒色領域を取り除くことです。そこでは画像の一部も失われますが、結果はすっきりした矩形の画像になります。以下はPythonコードです。

ここでは、以下のように画像の三つの主要なコーナーを見つける:

enter image description here

私はそれらの値をマークしています。 (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() 

今、私たちは、あなたが(1,1)の長方形と(x、y)を描く場合は、以下のようになりますminimum values in (far.x,xmax) and (far.y, ymax)

x = min(far[0],xmax) 
y = min(far[1],ymax) 

を見つける:

enter image description here

イメージをトリミングして、矩形領域を修正します。以下は

img2 = img[:y,:x].copy() 

結果である:あなたはおそらく、あなたの画像コンテンツのエクステントを取得するためにcvFindContoursを使用し、それに切り取ることができ

enter image description here

See, the problem is that you lose some parts of the stitched image.

+1

:私はC++にもっと精通しており、PythonのコードをC++に変換しようとしましたが、成功することができませんでした.C++言語で同じコードを共有できたら、とても感謝しています。 –

+0

申し訳ありませんが、私はC++で良くありません。しかし、あなたが私の方法のステップについて疑問がある場合は、私はもっと簡単な方法で説明することができます。 –

+0

:私はapproxpolyDPまでのすべてのステップを行ったが、私はCの座標点の積を計算する方法を知らないし、疑似コードも使用していると思う.Cの座標点の積私がapproxpoly()メソッドを適用した後の私のイメージを参照するには、[http://i.imgur.com/Qfoyt.jpg?1]があります。 approxpolyDp()を適用した後の同じ出力イメージ –

0

アクティブな輪郭(バルーン/ヘビ)を使用して、黒い領域を正確に選択することができます。デモンストレーションはhereです。アクティブな輪郭線はOpenCVで利用可能です。cvSnakeImageをチェックしてください。

+0

黒い部分を取り除くための実装方法を教えてください。 –

8

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]] 

はこのように見える終わる: enter image description here

注:ソートは、生の画像と必要になることが、圧縮された画像を使用して、低いしきい値を使用している場合、いくつかの圧縮アーチファクトが表示されるまで発生しないことがあり、だからこそ私は仕分けして後処理したのです。

希望に役立ちます!

+0

+1素晴らしい実例。 – karlphillip

関連する問題