マスク画像に穴をあけ​て写真と重ねる方法に​ついて教えてください​。

6 views (last 30 days)
phi
phi on 7 Jun 2022
Answered: phi on 8 Jun 2022
マスク画像の作成で困っています。
写真 に黒いマスク画像を重ねて、何か所か穴をあけて下の写真をその穴の所だけ表示させようとしています。写真とマスクは同じサイズです。 205 * 300 * 3 uint8
具体的な困りごとは2点、
(1)マスク画像に楕円を追加するとサイズが2倍近く拡大する。436 * 691 * 3 uint8
(2)(1)を写真と同じサイズにして写真に重ねると、今後は(1)が写真より約20%縮小する。(添付参照)
疑問は、写真と(2)は全く同じ値(205*300*3 uint8)なのに  なぜ綺麗に重ならないのか、です。
マスクに穴を描いたら、穴をあけるために 画像データにしてalphaを追加する必要があると思っています。思いつく解決法は
その前に(2)のサイズ修正も必要なので、サイズのズレの原因がFigureの余白なら削除するか、
mask_roi(roi)で生成される img は写真と同じサイズ205*300*3 uint8なので画像データに変換してalphaを追加するか、
だと思い調べていますがうまくいかずとても困っています。  
もし解決方法をおわかりでしたらぜひ教えてください。どうぞよろしくお願い致します。
今の処理の流れは以下の通りです。
同じサイズの写真とマスクを用意する(a) ==> マスクに穴を描く(b) ==> マスクに穴をあける(c)==> マスクのサイズが大きくなるので(msked)写真と同じサイズに切り出す(d) ==>マスクに透明度を追加する(e)→重ねる(f)
メイン================================
(a) 同じサイズの写真とマスク画像を用意する
rgb = imread('shashin.png');
roi = imread('kuro.png');
mask_roi(roi);
(d) この時点で(b)の戻り値であるマスクのサイズが大きくなっているので写真と同じサイズに切り出す
f = gcf;
cx_start = f.Position(1,1)/2-205/2;
cx_end = cx_start + 205;
cy_start = f.Position(1,2)/2-300/2;
cy_end =cy_start + 300;
mask=imread('msked.png');
msk1= imresize(mask,205/436);
msk1 = msk1(1:205,1:300,1:3);
imshow(rgb)
hold on
(e) マスクに透明度を追加する
msk1 = msk1 > 1; 穴を透明にする
msk1 = uint8(msk1); unit8にして
(f)重ねる
masked_rgb = rgb .* (msk1); % 元画像とマスクのANDを取る
imshow(masked_rgb) ここで重なった画像が表示されますが、添付のとおりサイズが合いません。
メインはここまで=========================
(b) マスクに円を描く
function ellipses = ellipse(x,y,a,b,inclination,c) % 穴の位置サイズ傾きを調べて楕円を描く関数
x,y=穴の中心点, a,b=短軸長軸の長さ, inclination=傾き, c=
inclination = inclination*pi/180;
rotation_matrix = [cos(inclination) -sin(inclination); sin(inclination) cos(inclination)];
th = 0:pi/50:2*pi;
x_ellipse = a * cos(th);
y_ellipse = b * sin(th);
ellipse_pts = rotation_matrix*[x_ellipse; y_ellipse];
x_ellipse = ellipse_pts(1, :) + x;
y_ellipse = ellipse_pts(2, :) + y;
ellipses = plot(x_ellipse, y_ellipse);
fill(x_ellipse, y_ellipse, c)
hold off
axis equal
end
(c) マスクに穴をあける
function mask_roi function(roi)
% x,y=穴の中心点, a,b=短軸長軸の長さ, inclination=傾き, c=色
msked= ellipse(x,y,a,b,inclination,c);
saveas(msked,'msked.png'); % 透明度を追加するため、一旦pngで保存しています。

Accepted Answer

phi
phi on 8 Jun 2022
自己解決しました。
(d)以降を書き換えました。膨張したサイズを縮小してから切り抜きました。念のため書いておきます。
理想は、ellipses functionの戻り値が膨張しないようにしたかったので、邪道な解決方法かもしれませんが。
Image Processing Toolbox の drawellipse でも、楕円を描けます。
f = gcf;
saveas (f,'./ROI2.png');
r = imread('ROI2.png');
r = imresize(r,0.65);
Icropped = imcrop(r,[80,30,299,204]);
Icropped = rgb2gray(Icropped);
img = Icropped > 1;
img = uint8(img);
masked_rgb = rgb .* (img); % 元画像とマスクのANDを取る

More Answers (0)

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!