繁体   English   中英

通过反射线反射RGB图像中的点(MATLAB)

[英]Reflecting points in an RGB image over a reflection line (MATLAB)

我有一个大小为MxNx3的RGB图像。 让我们想象一下,我们在图像的下半部分有一条反射线。 如何将线上方的所有点反映到线上? 我知道我需要做什么,但我无法在MATLAB上做到正确。 谢谢你的帮助。

例如,在下面的图像中,蓝线是反射线。

在此输入图像描述

%%// 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典型面具看起来像 -

在此输入图像描述

产量

在此输入图像描述

注意:用户必须在左侧准确选择两个点来表示蒙版的左侧边框,并且右侧边缘上恰好选择两个点。 此外,线上必须有足够的图像像素才能在线上反射。

我假设线存储在掩码中,如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,:,:);

在这里你看到结果(一步一步);

在此输入图像描述

为了生成该图像,我使用了以下代码:

% 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');

假设已经定义了这条线,那么解决这个问题的简单方法就是扫描每一列,并从该线的位置开始,以相反的顺序从线上方复制尽可能多的元素。

因此,对于每列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

这也假设线上方有足够的数据来填充线下方的区域。 如果没有,你将不得不决定如何处理这种情况。

我确定有办法对此进行矢量化并取出循环,但我会将其留给专家:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM