以下の画像に示されているように、私のセグメント化の結果(分水化法によって行われたセグメント化)の中には、残っているものがあります。私は何とか矩形だけが残るように画像を切り抜きたい。この操作は長方形の形状にのみ基づいており、強度レベルには関係しません。画像セグメントの残り物を枝刈りする
0
A
答えて
5
ソリューションの説明
私は、次のアプローチをお勧め:
-
を
は、幾何学的特性に従って形状の4つのコーナーの初期推測を生成します(詳細については、以下のコードを参照してください)。
対応するコーナーの各ペアの間に線を引いて、これらの4つのコーナーを指定して四角形を作成します。
境界画像のJaccard係数と生成された四角形マップを最適化するコーナーを見つけます。
時間を空けるために、最適化段階はローカルで行われます。私たちは、特定の地域で達成可能な最高のコーナーで各コーナーを置き換えるよう努めます。 4つのコーナーのそれぞれに改善がない場合、最適化段階を停止します。
コード
%reads image
gray = rgb2gray(imread('Bqx51.png'));
I = gray>0;
%extract boundries
B = bwboundaries(I,8);
B = B{1};
boundriesImage = zeros(size(I));
boundriesImage(sub2ind(size(I),B(:,1),B(:,2))) = 1;
%finds best 4 corners
[ corners ] = optimizeCorners(B);
%generate line mask
linesMask = drawLines(size(I),corners,corners([2:4,1],:));
%fill holes
rectMask = imfill(linesMask,'holes');
%noise reduction
rectMask = I & rectMask;
rectMask = imopen(rectMask,strel('disk',2));
%calculate result
result = gray;
result(~rectMask) = 0;
%display results
figure,imshow([gray, 255*ones(size(I,1),1),result]);
コーナー最適化機能
function [ corners] = optimizeCorners(pnts)
%OPTIMIZE4PTS Summary of this function goes here
% Detailed explanation goes here
Y = pnts(:,1);
X = pnts(:,2);
corners = getInitialGuess(X,Y);
boundriesIm = zeros(max(Y),max(X));
boundriesIm(sub2ind(size(boundriesIm),pnts(:,1),pnts(:,2))) = 1;
%R represents the search radius
R = 3;
%continue optimizing as long as there is no change in the final result
unchangedIterations = 0;
while unchangedIterations<4
for ii=1:4
%optimize corner ii
currentCorner = corners(ii,:);
bestCorner = currentCorner;
bestRes = calcEnergy(boundriesIm,corners);
cornersToEvaluate = corners;
candidateInds = sum(((repmat(currentCorner,size(X,1),1)-[Y,X]).^2),2)<(R^2);
candidateCorners = [Y(candidateInds),X(candidateInds)];
for jj=length(candidateCorners)
xx = candidateCorners(jj,2);
yy = candidateCorners(jj,1);
cornersToEvaluate(ii,:) = [yy,xx];
res = calcEnergy(boundriesIm,cornersToEvaluate);
if res > bestRes
bestRes = res;
bestCorner = [yy,xx];
end
end
if isequal(bestCorner,currentCorner)
unchangedIterations = unchangedIterations + 1;
else
unchangedIterations = 0;
corners(ii,:) = bestCorner;
end
end
end
end
計算エネルギー関数
function res = calcEnergy(boundriesIm,corners)
%calculates the score of the corners list, given the boundries image.
%the result is acutally the jaccard index of the boundries map and the
%lines map
linesMask = drawLines(size(boundriesIm),corners,corners([2:4,1],:));
res = sum(sum(linesMask&boundriesIm))/sum(sum(linesMask|boundriesIm));
end
コーナーが機能するために最初の推測を見つける
function corners = getInitialGuess(X,Y)
%calculates an initial guess for the 4 corners
corners = zeros(4,2);
%preprocessing stage
minYCoords = find(Y==min(Y));
maxYCoords = find(Y==max(Y));
minXCoords = find(X==min(X));
maxXCoords = find(X==max(X));
%top corners
topRightInd = find(X(minYCoords)==max(X(minYCoords)),1,'last');
topLeftInd = find(Y(minXCoords)==min(Y(minXCoords)),1,'last');
corners(1,:) = [Y(minYCoords(topRightInd)) X((minYCoords(topRightInd)))];
corners(2,:) = [Y(minXCoords(topLeftInd)) X((minXCoords(topLeftInd)))];
%bottom corners
bottomRightInd = find(Y(maxXCoords)==max(Y(maxXCoords)),1,'last');
bottomLeftInd = find(X(minYCoords)==min(X(minYCoords)),1,'last');
corners(4,:) = [Y(maxXCoords(bottomRightInd)) X((maxXCoords(bottomRightInd)))];
corners(3,:) = [Y(maxYCoords(bottomLeftInd)) X((maxYCoords(bottomLeftInd)))];
end
(@Sueverにより、以下answerから採取された)drawLine関数
function mask = drawLines(imgSize, P1, P2)
%generates a mask with lines, determine by P1 and P2 points
mask = zeros(imgSize);
P1 = double(P1);
P2 = double(P2);
for ii=1:size(P1,1)
x1 = P1(ii,2); y1 = P1(ii,1);
x2 = P2(ii,2); y2 = P2(ii,1);
% Distance (in pixels) between the two endpoints
nPoints = ceil(sqrt((x2 - x1).^2 + (y2 - y1).^2));
% Determine x and y locations along the line
xvalues = round(linspace(x1, x2, nPoints));
yvalues = round(linspace(y1, y2, nPoints));
% Replace the relevant values within the mask
mask(sub2ind(size(mask), yvalues, xvalues)) = 1;
end
結果
最初の画像(前後):
秒画像(前後):
ランタイム
Elapsed time is 0.033998 seconds.
可能な改善/提案
エネルギー関数も(で同様の傾きを持つように平行線を奨励制約を含んでいてもよいですあなたの例は同じ勾配を持っていません)。
エネルギー関数には、各角が90度に近づくように促す制約が含まれている場合があります。
小さなアーチファクトを排除するためにこのアプローチを実行する前にノイズリダクション段階(imcloseなど)を行うことができます。
アルゴリズムをいくつかの初期推測で実行し、最適なアルゴリズムを選択することは可能です。
この解決策は最良の四角形を推定するものではなく、最良の四角形を推定することに注意してください。その理由は、入力画像が長方形ではない(線が平行でない)ためです。
関連する問題
- 1. gitの枝刈りの違い
- 2. Rテキスト2vecのテキストコーパスに文書の枝刈りの効果をプロットする
- 3. ニットからの残り物
- 4. アップロード画像ファイルと、残りAPIに
- 5. 画像処理:画像の「ゼブラ」をセグメント化する
- 6. Azure RMテンプレートネストされたテンプレート残り物
- 7. 情報利得枝刈り機能の文脈におけるアルファの意味は何ですか?
- 8. itk - 3D画像のセグメント化
- 9. 残りの画像ファイルを受信します。Api
- 10. 残りの管理者の画像にあるカスタムタイトル
- 11. Javascript - ページの残りの部分の前に画像をロード
- 12. モバイルデバイスで表示される画像は残りますが、残りのコンテンツは表示されます
- 13. アルファベータ刈り込みの転置テーブル
- 14. Angularjsで残りのAPIを使用して画像をアップロード
- 15. EIGEN:疎行列の乗算は枝刈りされた結果を生成しません
- 16. 作物アンドロイド画像
- 17. 背景画像 - 残りの半分のテキスト
- 18. 画像にドットオンクリックを残す
- 19. MonoTouch(iPhone)の人物を切り抜いた画像を取得する
- 20. セグメント画像と各セグメントに注釈を付ける&ここで各セグメント
- 21. 画像base64文字列問題残りのAPIクライアントon chrome
- 22. Jssorスライダの利用可能な画像と残りの画像の数を取得する
- 23. MATLABでセグメント化された画像に色を割り当てる
- 24. カードを処理して残り物を返す
- 25. コンジットの残り物のメリットは何ですか?
- 26. Docker initデーモンのベストプラクティス(PID 1ゾンビ刈り取り)
- 27. 画像ピンチズームにScrollViewerを使用すると、パンにスナップが残ります
- 28. どのセグメントI iはセグメントに8つのブロックに画像を必要ような画像を有し、OpenCVの
- 29. numpy/pythonでのFloodfillセグメント化画像
- 30. 未使用の画像の残りの部分を隠す方法
興味深い質問だと思います!あなたが明確なアイデアを持っていない場合、私にいくつかのヒントを与えてください。そうすれば、あなたの考えを使って完全な解決策を見つけることができます。 – Woeitg
不明です。左のイメージはソースですか?そうでない場合は、ソースイメージを表示し、セグメント化の仕方を説明できますか?それはあなたの問題に関連している可能性があるためです。 – kebs
また、あなたが持っているもののいくつかのコードスニペットを示してください。これはOpenCV関連ですか?その場合は、タグを追加します。 – kebs