2値化した画像から座標を取得する

32 views (last 30 days)
竣也 辻本
竣也 辻本 on 7 Oct 2021
Edited: Atsushi Ueno on 19 Oct 2021
線香を燃やした画像(下の画像)を2値化処理を行い。そこから任意(ほかのx座標の画像処理を行いたいため)のx座標から灰の下端のy座標を算出したいです。
2値化処理した画像は以下の通りです
2値化した条件は以下の通りです。
  1 Comment
Atsushi Ueno
Atsushi Ueno on 9 Oct 2021
私は人ですが画像を見ても何が写っているのか理解できず、「光の筋はスミアかな?」とか、丸棒の端面をみて「蚊取り線香の渦かな?」などと思っていました。後日サムネイル表示をみてやっと理解しました。
  • 背景は暗闇のモノクロ写真
  • 金属の丸棒が2本、間隙を設けて水平な同一軸上に配置されている
  • 間隙内、左側の丸棒の端面に近い方に棒線香が垂直に立っている
  • 金属棒の端面と側面の一部が光の反射の為か白く写っている
  • 棒線香の燃焼部分も白く写っている(輝度値255/255)
  • 棒線香の煙も薄い白で写っている(燃焼部分の上部に立ち昇る)
  • 燃焼部分の周囲に濃い白の煙? が写っている
  • 棒線香のX座標はおそらく間隙内(丸棒の端面間)を移動する

Sign in to comment.

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 9 Oct 2021
Edited: Atsushi Ueno on 9 Oct 2021
不明な背景情報はある程度想定して、目的の「灰の下端のy座標」に印を付けてみました。二値化(可変閾値法)については、aの値を色々変えて試してみましたが、本回答の方法では単純な二値化で灰の下端のy座標を求める事が出来ました。もっと賢い方法でないと駄目ですかね。
  • 棒線香の移動範囲が丸棒の端面間なら、反射光は線香のx軸位置を侵害しない(想定)
  • 灰の下端(白く光る燃焼部分)の高さがある程度一定である事を検出条件にする
  • 灰の下端(白く光る燃焼部分)が煙や反射光で覆い隠されてしまうと想定が崩れてしまう
I = imread('senko.bmp'); % 質問と同じ画像
imshow(I); hold on;
B = I > 254; % 二値化(下記の二値化関数binarize_var_thr(可変閾値法)も試してみた)
H = sum(B,1); % 白い画素の数(縦方向)
plot(H); % 青い線で表示
LM = find(islocalmax(H,'MinProminence',55)); % 青線のピーク(丸棒端面の反射光(縦長))のX座標を探す
if(numel(LM) == 2) % ピークを2個検出する様↑このMinProminence値を調整する
xline(LM(1),'Color','y'); xline(LM(2),'Color','y'); % 端面に黄色の縦線を引いてみる
H([1:LM(1) LM(2):end]) = 0; % 端面の反射光を利用して、棒線香の検出範囲を端面間に絞る
end
H(H > 20) = 0; % 大きな塊(丸棒の反射光や煙)は除く
plot(H); % 橙色の線で表示
senkoX = round(mean(rmoutliers(find(H)))); % 棒線香のx座標(indexの外れ値を除き平均)
senkoY = round(mean(rmoutliers(find(B(:,senkoX))))); % 棒線香のy座標(indexの外れ値を除き平均)
xline(senkoX,'Color','w'); % 棒線香のx座標を白い線で表示
yline(senkoY,'Color','w'); % 棒線香のy座標を白い線で表示
function newX = binarize_var_thr(X0) % 二値化(可変閾値法)
X1 = double(X0);
[M,N] = size(X1);
newX = zeros(M, N);
a = 7;
for m = 1:M
for n = 1:N
m1 = m - a; if m1 < 1; m1 = 1; end
m2 = m + a; if m2 >= M; m2 = M; end
n1 = n - a; if n1 < 1; n1 = 1; end
n2 = n + a; if n2 >= N; n2 = N; end
W = X1(m1:m2, n1:n2);
meanW = mean(W(:));
stdW = std(W(:));
if stdW / meanW >= 0.6 && X1(m, n) <= meanW
newX(m,n) = 255;
end
end
end
end
  2 Comments
竣也 辻本
竣也 辻本 on 19 Oct 2021
このプログラムでさらにx座標(線香の位置)を自分で指定して固定し、そのときのy座標(線香の灰の下端)を出したいのですがその場合どのような変更を加えれば良いのでしょうか?
Atsushi Ueno
Atsushi Ueno on 19 Oct 2021
Edited: Atsushi Ueno on 19 Oct 2021
(´;ω;`)ブワッ
このような変更を加えれば良いです
I = imread('senko.bmp'); % 質問と同じ画像
imshow(I); hold on;
B = I > 254; % 二値化(下記の二値化関数binarize_var_thr(可変閾値法)も試してみた)
[senkoX, ~] = ginput; % 対話的に、カーソルを線香に合わせてクリックして、Enterキーを押す
senkoX = round(senkoX(end)); % 最後にクリックした座標のみ取得し整数化
senkoY = round(mean(rmoutliers(find(B(:,senkoX))))); % 棒線香のy座標(indexの外れ値を除き平均)
xline(senkoX,'Color','w'); % 棒線香のx座標を白い線で表示
yline(senkoY,'Color','w'); % 棒線香のy座標を白い線で表示

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!