【问题标题】:How to do circular crop using matlab?如何使用matlab进行圆形裁剪?
【发布时间】:2013-11-15 01:53:48
【问题描述】:

我通常使用imcrop 来裁剪矩形图像,但我想创建圆形裁剪。怎么做?

我知道还有一个关于这个的问题,这里是链接:

  1. MATLAB: how do I crop out a circle from an image

    [xx,yy] = ndgrid((1:imageSize(1))-ci(1),(1:imageSize(2))-ci(2));
    mask = (xx.^2 + yy.^2)<ci(3)^2;
    

    imshow(mask) 的结果是白色背景的矩形

  2. Cropping Circular region of interest around a point in MATLAB

    roimaskcc 中的错误

  3. http://www.mathworks.com/matlabcentral/newsreader/view_thread/242489

    [xx,yy]=ndgrid(1:size(X,1), 1:size(X,2));
    CroppingMask= ( (xx-Xcenter).^2+(yy-Ycenter).^2<=Radius^2 );
    X=X.*CroppingMask;
    

    imshow(CroppingMask) 的结果是一个黑色背景的矩形,矩形中心有一个小的白色圆形。当我运行第 3 行时,它显示错误。

请帮助我,一步一步,因为我是初学者。

这是我的图片:https://www.dropbox.com/s/5plqzqgyb1ej6gh/patricia.jpg。分辨率为 480x640。

【问题讨论】:

  • 您引用的第一个圆形蒙版问题在 256x256 图像上为ci = [100 100 20] 提供了一个漂亮的小圆圈。

标签: matlab image-processing


【解决方案1】:

解决方案 (1) 效果很好。这是一个使用您的图像的完整工作示例。

I = imread('patricia.jpg');
imageSize = size(I);
ci = [250, 300, 100];     % center and radius of circle ([c_row, c_col, r])
[xx,yy] = ndgrid((1:imageSize(1))-ci(1),(1:imageSize(2))-ci(2));
mask = uint8((xx.^2 + yy.^2)<ci(3)^2);
croppedImage = uint8(zeros(size(I)));
croppedImage(:,:,1) = I(:,:,1).*mask;
croppedImage(:,:,2) = I(:,:,2).*mask;
croppedImage(:,:,3) = I(:,:,3).*mask;
imshow(croppedImage);

它会生成以下图像。

我希望这可以澄清事情。可能有更好的方法来重新组合裁剪的图像,但这是我能想到的。

【讨论】:

  • 感谢您的回复,但我收到此错误,错误使用 .* 整数只能与同一类的整数或标量双精度数组合。
  • 已解决-我用这个mathworks.com/help/matlab/ref/double.html谢谢先生,这很有帮助..
  • 对不起。我正在使用 GNU Octave(一个免费的 MATBLAB 克隆),这就是代码对我有用但你得到“错误使用 .* ...”的原因。我很高兴你找到了解决方案。我会更新我的代码。我不知道你说的清除黑色区域是什么意思? Matlab 使用矩阵,imshow 显示矩阵的所有值。黑色区域只是很多零,渲染时在图中显示为黑色像素。您可以做的是将图像保存为 PNG 并将黑色区域指定为透明(例如参见 this answer)。也许这就是你想要的?
  • 我猜Matlab可以清除黑色区域。谢谢,非常有帮助,抱歉打扰了您的时间。
【解决方案2】:

这是一个非交互式裁剪的选项:

R=20; % radius in pixels
x=10;y=10; %Location of upper-right corner of your cropping mask

Mask = fspecial('disk',R)~=0;
[u v i]=size(Mask);

Cropped= imcrop(I,[x y u v]).*Mask;

【讨论】:

  • 我认为x+uy+v应该是uv这里
【解决方案3】:

您希望最终输出看起来如何?根据 MA​​TLAB 中的定义,您不能拥有这样的“圆形”图像 - 只是一个常规图像,其中圆外的所有点都设置为某个背景值。但是,可以使用imwritegifpng 格式以透明背景保存图像。

这是一个使用 imroi 方法的示例(需要图像处理工具箱)

I = imread('cameraman.tif');
h = imshow(I);

% define circular roi by square bounding box
x = 10;
y = 10; 
d1 = 100;
d2 = 100; 
e = imellipse(gca, [x y d1 d2]);

% roi can be interactively moved/adjusted
% do not close figure window before createMask is called

%%% these lines are only needed if you move or resize the roi
   pos = getPosition(e);
   x = pos(1);
   y = pos(2);
   d1 = pos(3);
   d2 = pos(4);
%%%

BW = createMask(e,h);
% here assuming your image is uint8
BW = uint8(BW);

I2 = I.*BW; % everything outside circle to black
I2 = I2(x:(x+d1-1),y:(y+d2-1)); % close crop to circle
imwrite('out.png',I2,'Transparency',0);

在这种情况下,使用'Transparency',0 会将所有黑色 (0) 像素设置为透明。如果您感兴趣的区域内有实际的黑色像素,它也会使这些像素透明。如果这可能是一个问题,您可以将BW 裁剪为与I2 相同的大小,并设置“Alpha”而不是Transparency(有关详细信息,请参阅imwrite 文档)。

【讨论】:

    【解决方案4】:

    我认为您的问题的解决方案是使用 imcrop 裁剪一个正方形并使用以下代码覆盖一个圆圈:

    function imout = overlay_circle(im)
    u = size(im);
    mx = ceil(u(2)/2);
    my = ceil(u(1)/2);
    if (length(u)==3),
        for x=1:u(2),
            for y=1:u(1),
                if (x-mx)^2 + (y-my)^2 > mx^2,
                    im(y,x,1) = 0;
                    im(y,x,2) = 0;
                    im(y,x,3) = 0;
                end
            end
        end
    else,
        for x=1:u(2),
            for y=1:u(1),
                if (x-mx)^2 + (y-my)^2 > mx^2,
                    im(y,x) = 0;
                end
            end
        end
    end
    imout = im;
    

    【讨论】:

    • 感谢您的回复,我创建了 im 变量,im = imread('patricia.jpg');但是当我使用上面的代码时,它显示错误 Error: Function definitions are not allowed in this context.
    • 你可能需要在一个名为 overlay_circle.m 的文件中定义函数
    【解决方案5】:
    I = imread('patricia.jpg');
    imageSize = size(I);
    ci = [250, 300, 100];     % center and radius of circle ([c_row, c_col, r])
    [xx,yy] = ndgrid((1:imageSize(1))-ci(1),(1:imageSize(2))-ci(2));
    mask = uint8((xx.^2 + yy.^2)<ci(3)^2);
    croppedImage = uint8(zeros(size(I)));
    croppedImage(:,:,1) = I(:,:,1).*mask;
    imshow(croppedImage);
    

    【讨论】:

    • 你能解释一下你的答案吗?为什么您的答案优于/不同于其他答案?
    猜你喜欢
    • 2023-03-20
    • 2013-10-05
    • 2016-04-27
    • 2011-09-25
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多