我有一张大小为MxNx3的RGB图像。让我们想象一下,我们在图像的下半部分有一条反射线。如何将线上方的所有点反映到线上?我知道我需要做什么,但我无法在MATLAB上做到正确。谢谢你的帮助。
例如,在下图中,蓝线是反射线。
答案 0 :(得分:3)
<强>代码强>
%%// Read input image
img =imread(IMG_FILEPATH);
%%// Let user select the mask, top of which will basically act
%%// as the reflection line
figure,imshow(img)
[mask,xi,yi] = roipoly(img);
%%// Remove the last element as that is same as the first one
xi(end)=[];
yi(end)=[];
%%// Find the two corner points each on the left and right sides of the mask
pt_matrix = [xi yi]
[val,ind] = sort(xi)
left_two_pts = pt_matrix(ind(1:2),:)
right_two_pts = pt_matrix(ind(end-1:end),:)
four_pts = round([left_two_pts;right_two_pts])
%%// Remove a 5x5 neighborhood around the four corners, so that biggest
%%// blob that is the line could be separated out
BW1 = edge(mask,'canny');
for k = 1:4
BW1(four_pts(k,2)-2:four_pts(k,2)+2,four_pts(k,1)-2:four_pts(k,2)+1) = 0;
end
%%// Get the biggest blob that is the reflection line
[L, num] = bwlabel(BW1);
counts = sum(bsxfun(@eq,L(:),1:num));
[~,ind] = max(counts);
BW1 = (L==ind);
%%// Connect the endpoints of the line to left and right sides of the image
xlimit = [find(sum(BW1,1),1) find(sum(BW1,1),1,'last')];
[row1,col1] = ind2sub(size(BW1),find(BW1));
BW1(row1(1),1:col1(1)-1)=1;
BW1(row1(end),col1(end)+1:end)=1;
%%// Select only one per column for the reflection
[xt0,yt0] = find(BW1);
[yt1,a2,a3] =unique(yt0,'first');
xt1=xt0(a2);
sz1 = size(BW1,1)-xt1;
%%// Perform the reflection
for k = 1:numel(yt1)
img(xt1(k):end,k,:) = img(xt1(k):-1:xt1(k)-sz1(k),k,:);
end
figure,imshow(img)
roipoly
的典型掩码看起来像 -
<强>输出强>
注意:用户必须在左侧准确选择两个点来表示蒙版的左侧边框,并选择右侧边缘的两个点。此外,线上必须有足够的图像像素才能反射到线上。
答案 1 :(得分:3)
我假设线存储在掩码中,如OP所述。我将假设面具在线上方是黑色,在它下面是白色。这是解决问题的“奇特”方式。 :)
% 1. Open your image (MxNx3 matrix).
img = im2double(imread('original.png'));
% 2. Open your 'line image' as a logical array (MxNx3 matrix)
line = imread('line.png') > 0;
% 3. Now, we will "align" the upper part of the image based on the line,
% so that the line will be straight at the bottom of the image. We will
% do that by sorting the 'line image', moving the ones of the mask
% above. The code was adapted from:
% http://www.mathworks.com/matlabcentral/newsreader/view_thread/28715
upper = zeros(size(line));
upper(~line) = -1;
upper = sort(upper, 'descend');
upper(upper == -1) = img(~line);
% 4. Let's concatenate both the image with it's mirror below.
imgConcat = [upper; upper(end:-1:1, :, :)];
% 5. Also, The line mask will be concatenated to it's negative, and we'll
% invert the order of the rows.
lineConcat = [line; ~line];
lineConcat = lineConcat(end:-1:1,:,:);
% 6. Now we repeat the "alignment procedure" used on step 4 so that the
% image will be positioned on the upper part. We will also remove the
% lower part, now containing only zeros.
mirror = zeros(size(lineConcat));
mirror(lineConcat) = -1;
mirror = sort(mirror, 'ascend');
mirror(mirror == -1) = imgConcat(lineConcat);
mirror = mirror(1:end/2,:,:);
Here你看到了结果(一步一步);
为了生成该图像,我使用了以下代码:
% Display the results, step by step (final result is in the 'mirror' matrix).
subplot(2,3,1), imshow(img, []); title('Step 1. Original image')
subplot(2,3,2), imshow(double(line), []); title('Step 2. Line image');
subplot(2,3,3), imshow(upper, []); title('Step 3. Image "alignment"');
subplot(2,3,4), imshow(imgConcat, []); title('Step 4. Mirror concatenation');
subplot(2,3,5), imshow(double(lineConcat), []); title('Step 5. Mask concatenation');
subplot(2,3,6), imshow(mirror, []); title('Step 6. Result by a final alignment');
答案 2 :(得分:0)
假设已经定义了这条线,那么解决这个问题的简单方法就是扫描每一列,从线的位置开始,从线上方复制尽可能多的元素,以适应线下方,逆序。
因此,对于每列c
,请line[c]
为该列中该行的行号。然后
maxR = size(c);
c(line[c]:end) = c(line[c]-1:-1:line[c]-(maxR - line[c] + 1));
最后,line[c]-(maxR - line[c] + 1)
部分告诉它要复制多少。它只需要将列底部与线条之间的距离,并将其用作要复制的像素数。
当然,这必须推广到3个频道,但我不想弄乱这个概念。除此之外,您只需将其放在所有列c
上的循环中。
这也假设线上方有足够的数据来填充线下方的区域。如果没有,你将不得不决定如何处理这种情况。
我确信有办法对此进行矢量化并取出循环,但我会将其留给专家:)