Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 通过显示一个相邻的图像(以对角线分隔),合并两个图像_Image_Matlab_Merge_Image Manipulation_Image Comparison - Fatal编程技术网

Image 通过显示一个相邻的图像(以对角线分隔),合并两个图像

Image 通过显示一个相邻的图像(以对角线分隔),合并两个图像,image,matlab,merge,image-manipulation,image-comparison,Image,Matlab,Merge,Image Manipulation,Image Comparison,我有两个图像(“之前”和“之后”)。我想展示一个最终的图像,其中左半部分取自前图像,右半部分取自后图像 图像应以预定义宽度(2或3像素)的白色对角线分隔,其中对角线由特定角度或2个起点和终点坐标指定。对角线应覆盖最终图像的一部分,使其大小与源的大小相同 例如: 我知道可以通过在所有像素上循环来重新组合并创建最终图像,但是有没有一种有效的方法,或者更好的方法,一个内置函数可以做到这一点?一个解决方案: im1 = imread('peppers.png'); im2 = repmat(rgb2g

我有两个图像(“之前”和“之后”)。我想展示一个最终的图像,其中左半部分取自前图像,右半部分取自后图像

图像应以预定义宽度(2或3像素)的白色对角线分隔,其中对角线由特定角度或2个起点和终点坐标指定。对角线应覆盖最终图像的一部分,使其大小与源的大小相同

例如:

我知道可以通过在所有像素上循环来重新组合并创建最终图像,但是有没有一种有效的方法,或者更好的方法,一个内置函数可以做到这一点?

一个解决方案:

im1 = imread('peppers.png');
im2 = repmat(rgb2gray(im1),1,1,3);

imgsplitter(im1,im2,80) %imgsplitter(image1,image2,angle [0-100])

function imgsplitter(im1,im2,p)
    s1  = size(im1,1); s2 = size(im1,2);
    pix = floor(p*size(im1,2)/100);
    val = abs(pix -(s2-pix));
    dia = imresize(tril(ones(s1)),[s1 val]);
    len = min(abs([0-pix,s2-pix]));
    if p>50
        ind = [ones(s1,len) fliplr(~dia) zeros(s1,len)];
    else
        ind = [ones(s1,len) dia zeros(s1,len)];
    end
    ind = uint8(ind);
    imshow(ind.*im1+uint8(~ind).*im2)
    hold on 
    plot([pix,s2-pix],[0,s1],'w','LineWidth',1)
end
输出:

不幸的是,我不相信您的问题有一个内置的解决方案,但我已经开发了一些代码来帮助您做到这一点,但不幸的是,它需要图像处理工具箱来很好地处理代码。正如你在评论中提到的,你已经有了这个,所以我们应该没问题

这背后的逻辑相对简单。我们将假定您的前后图片大小相同,并且共享相同数量的频道。第一部分是声明一个空白图像,然后我们沿着一定厚度的中间画一条直线。这背后的复杂性是声明一个略大于图像原始大小的图像。原因是因为我要在中间画一条线,然后将这个空白图像旋转一定角度,以达到你想要的第一部分。我将使用旋转图像的任何角度,你想要的。第一个本能反应是声明一个与原始图像大小相同的图像,在中间画一条线并旋转它。但是,如果执行此操作,最终将断开直线连接,而不会从图像的顶部到底部绘制。这是有意义的,因为在一个角度上绘制的线比垂直绘制的线覆盖更多的像素

利用毕达哥拉斯定理,我们知道在你的图像上能画出的最长的线是对角线。因此,我们在行和列中声明一个
sqrt(rows*rows+cols*cols)
,其中
rows
cols
是原始图像的行和列。之后,我们将采取天花板,以确保我们已经覆盖尽可能多,我们增加了一点额外的空间,以适应线的宽度。我们在这个图像上画一条线,旋转它,然后我们将裁剪后的图像,使其与输入图像的大小相同。这样可以确保以任意角度绘制的线完全从上到下绘制

这种逻辑是最难的部分。一旦你这样做了,你声明两个
逻辑
掩码,你用它们来填充掩码的左侧,作为一个掩码,我们将反转掩码来找到另一个掩码。您还需要使用我们先前使用
imrotate
创建的线条图像索引到遮罩中,并将值设置为
false
,以便忽略线条上的这些像素

最后,取下每个蒙版,索引到图像中,并复制到所需图像的每个部分。最后使用线条图像索引到输出中,并将值设置为白色

不用多说,下面是代码:

% Load some example data
load mandrill;

% im is the image before
% im2 is the image after
% Before image is a colour image
im = im2uint8(ind2rgb(X, map));

% After image is a grayscale image
im2 = rgb2gray(im);
im2 = cat(3, im2, im2, im2);

% Declare line image
rows = size(im, 1); cols = size(im, 2);
width = 5;
m = ceil(sqrt(rows*rows + cols*cols + width*width));
ln = false([m m]);
mhalf = floor(m / 2); % Find halfway point width wise and draw the line
ln(:,mhalf - floor(width/2) : mhalf + floor(width/2)) = true;

% Rotate the line image
ang = 20; % 20 degrees
lnrotate = imrotate(ln, ang, 'crop');

% Crop the image so that it's the same dimensions as the originals
mrowstart = mhalf - floor(rows/2);
mcolstart = mhalf - floor(cols/2);
lnfinal = lnrotate(mrowstart : mrowstart + rows - 1, mcolstart : mcolstart + cols - 1);

% Make the masks
mask1 = imfill(lnfinal, [1 1]);
mask2 = ~mask1;
mask1(lnfinal) = false;
mask2(lnfinal) = false;

% Make sure the masks have as many channels as the original
mask1 = repmat(mask1, [1 1 size(im,3)]);
mask2 = repmat(mask2, [1 1 size(im,3)]);

% Do the same for the line
lnfinal = repmat(lnfinal, [1 1 size(im, 3)]);

% Specify output image
out = zeros(size(im), class(im));
out(mask1) = im(mask1);
out(mask2) = im2(mask2);
out(lnfinal) = 255;

% Show the image
figure;
imshow(out);
我们得到:

如果你想让线朝另一个方向移动,只需使角度
ang
为负值即可。在上面的示例脚本中,我将角度设置为逆时针20度(即正)。要重现您给出的示例,请指定-20度。我现在看到这张图片:


这里有一个使用多边形的解决方案:

function q44310306
% Load some image:
I = imread('peppers.png');
B = rgb2gray(I);
lt = I; rt = B;
% Specify the boundaries of the white line:
width = 2; % [px]
offset = 13; % [px]
sz = size(I);
wlb = [floor(sz(2)/2)-offset+[0,width]; ceil(sz(2)/2)+offset-[width,0]];
%      [top-left, top-right;              bottom-left, bottom-right]
% Configure two polygons:
leftPoly  = struct('x',[1 wlb(1,2) wlb(2,2) 1],        'y',[1 1 sz(1) sz(1)]);
rightPoly = struct('x',[sz(2) wlb(1,1) wlb(2,1) sz(2)],'y',[1 1 sz(1) sz(1)]);
% Define a helper grid:
[XX,YY] = meshgrid(1:sz(2),1:sz(1));
rt(inpolygon(XX,YY,leftPoly.x,leftPoly.y)) = intmin('uint8');
lt(repmat(inpolygon(XX,YY,rightPoly.x,rightPoly.y),1,1,3)) = intmin('uint8');
rt(inpolygon(XX,YY,leftPoly.x,leftPoly.y) & ...
   inpolygon(XX,YY,rightPoly.x,rightPoly.y)) = intmax('uint8');
final = bsxfun(@plus,lt,rt);
% Plot:
figure(); imshow(final);
结果是:


所以你想要一个图像,它被分解成三个部分。。。第一部分是前图像的左半部分,中间是一条2或3像素宽但以一定角度旋转的白线图像,最后一部分是后图像的右半部分?有可能展示一个例子吗?是的,当然,我在edit.Aha中添加了一个例子。这个例子说明了一切。谢谢你添加它。你是否碰巧拥有图像处理工具箱?白线是否会覆盖图像的一部分,从而产生相同大小的图像或将其分开?@rayreng是的,我有,Leander它应该覆盖,以便最终图像大小与原始2图像相同。我在zeros函数中遇到错误:使用zeros类名输入的错误必须是有效的数字类名。我认为输入字符串“logical”不受支持。@StackPlayer您可能正在使用旧版本的MATLAB。它适用于R2016b。我已经更改了它,以便它适用于旧版本。@StackPlayer哈哈,没问题:)谢谢您的接受!这是一个有趣的问题。我第一次做这样的事情。@StackPlayer好的,我已经修好了。在裁剪之前,我刚刚在线条图像中添加了更多的填充。让我知道它是否有效。一个伟大的,一如既往,雷!