13

OpenCV関数とC++を使用して2つの画像をつなぎ合わせました。現在、最終的な画像に大きな黒い部分が含まれているという問題に直面しています。

最終的な画像は、有効な部分を含む長方形である必要があります。私の画像は次のとおりです。

ここに画像の説明を入力してください

黒い部分を削除するにはどうすればよいですか?

4

3 に答える 3

22

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.

于 2012-05-18T05:29:27.537 に答える
9

これは、 thresholdfindContours、および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]]

最終的には次のようになります。 ここに画像の説明を入力してください

注:生の画像では並べ替えは必要ない場合がありますが、圧縮画像を使用すると、低いしきい値を使用すると圧縮アーティファクトが表示されるため、並べ替えで後処理しました。

お役に立てば幸いです。

于 2012-05-17T18:09:42.397 に答える
0

アクティブな輪郭(バルーン/ヘビ)を使用して、黒い領域を正確に選択できます。デモはここにあります。アクティブな輪郭はOpenCVで利用できます。cvSnakeImageを確認してください。

于 2012-05-17T15:23:12.970 に答える