5

に深色に基づいて、接続面積をします。どのセグメントI iはセグメントに8つのブロックに画像を必要ような画像を有し、OpenCVの

Iは

img_gray = cv2.imread(input_file,cv2.IMREAD_GRAYSCALE) 
ret,thresh = cv2.threshold(img_gray,254,255,cv2.THRESH_BINARY) = 
kernel = np.array(cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3), (-1, -1))) 
img_open = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) 
cv2.imshow('abc',img_open) 
ret1,thresh1 = cv2.threshold(img_open,254,255,cv2.THRESH_BINARY_INV) # 
contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_CCOMP ,cv2.CHAIN_APPROX_NONE) 

for i in range(len(contours)): 
    if len(contours[i]) > 20: 
     x, y, w, h = cv2.boundingRect(contours[i]) 
     cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) 
     print (x, y),(x+w, y+h) 

閾値
enter image description here

後の最終結果が互いに接続いくつかのブロックは、私が期待ものではない大部分に形成される。この閾値法を試みました。 enter image description here enter image description here enter image description here 周り

+0

私はopenCVに慣れていませんが、バイナリしきい値を実行しているという事実に問題があると感じています。それはそこにあるかどうかです。しかし、あなたが必要とする結果は、行と行の両方の三項です。 'cv2.THRESH_BINARY'を使うのではなく、' cv2.THRESH_TRUNC'を実行してバックグラウンドを省略してから、バイナリ比較を行います。最後に両方の輪郭線を取得し、それらを結合すると、理論上は8つの領域になるはずです。 – Enfyve

+1

場所+深さに基づいて平均的なセグメント化を試みましたか? – Shai

+0

@Shai私は小区切りを調べます – user824624

答えて

4

私は試してみて、あなたの深さ勾配に基づいて車を分離アルゴリズムのスケッチを与えるでしょう。悲しいかな、単に大きな勾配の輪郭を見ると、車は完全に分離されていないので、境界輪郭の「洗練」が必要です。輪郭が完成したら、単純な連結成分クラスタリングで車を分離するだけで十分です。ここで

は私のコードは、(Matlabの中で、私はそれがOpenCVの同等の機能を見つけることがあまりにも複雑ではありませんかなり確信している)だ:

img = imread('http://i.stack.imgur.com/8lJw8.png'); % read the image 
depth = double(img(:,:,1)); 
depth(depth==255)=-100; % make the background VERY distinct 
[dy dx] = gradient(depth); % compute depth gradients 
bmsk = sqrt(dx.^2+dy.^2) > 5; % consider only significant gradient 
% using morphological operations to "complete" the contours around the cars 
bmsk = bwmorph(bwmorph(bmsk, 'dilate', ones(7)), 'skel'); 

% once the contours are complete, use connected components 
cars = bwlabel(~bmsk,4); % segmentation mask 
st = regionprops(cars, 'Area', 'BoundingBox'); 
% display the results 
figure; 
imshow(img); 
hold all; 
for ii=2:numel(st), % ignore the first segment - it's the background 
    if st(ii).Area>200, % ignore small regions as "noise" 
     rectangle('Position',st(ii).BoundingBox, 'LineWidth', 3, 'EdgeColor', 'g'); 
    end; 
end; 

出力は

enter image description here

そして

です

enter image description here

完璧ではありませんが、あなたを十分に近づけます。

さらに読書:

  • bwmorph:形態学的操作を実行します。
  • bwlabel:接続されたコンポーネントのセグメンテーションマスク(ラベリング)を出力する。
  • regionprops:イメージ領域の統計情報(領域やバウンディングボックスなど)を計算します。

考えて来て、深さは、このような素敵な勾配を持って、しきい値深度勾配をすることができますし、素敵な接続コンポーネントを取得します。

+0

depth = double(img(:、:、1));深さ(深度== 255)= - 100;私がこの2つを理解していないプログラムでは、img(:、:、1)はimgの赤いチャンネルを意味し、doubleを使用してデータ型をuint8から倍に変更します。深度(深度== 255)= -100と書くと、-100で置き換えられた深さの255の値すべてを置き換えることを意味します。問題は何が起こったのか、なぜこれを行うのですか? – user824624

1

単純なアプローチそれを得るために、任意の他の方法(しかし、それは作品)

ステップ1:グレースケールの画像を読んだ後、しきい値下の車を取得するために。

ret1, car_thresh1 = cv2.threshold(cars, 191, 254, 0) 

これは私にこれを与えました。 carsBottom

ステップ2:私これを与えたメイン画像

car_thresh2 = car_thresh1 - cars 

からこのイメージを引きます。 enter image description here

ステップ3:しきい値私は単にあなたが何をしたかしなかったそして、私は、このcarsTop

を与えた減算画像

ret3, cars_thresh3 = cv2.threshold(car_thresh2, 58, 255, 0) 

抽出しcarsTopで輪郭を描画するためのcarsBottomこれが結果です。 cars

+0

この方法では正面画像では機能しますが、最後の画像では失敗します – user824624

+0

長方形を描画しないで最後の画像を追加できますか? –

+0

類似の画像が更新されます – user824624

関連する問題