MATLAB Answers

Crop a circle from an image and put it on another image

166 views (last 30 days)
Ali Purse
Ali Purse on 27 Oct 2018
Answered: Image Analyst on 27 Oct 2018
May you please help me how to crop (cut) a circle from an image and put it on another image?
I know that I can crop a circle from an image using following code:
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);

  0 Comments

Sign in to comment.

Answers (2)

jonas
jonas on 27 Oct 2018
Edited: jonas on 27 Oct 2018
You were almost there, and given the error message I think you could have figured it out :)
"Integers can only be combined with integers of the same class, or scalar doubles."
croppedImage(:,:,1) = I(:,:,1).*uint8(mask);
croppedImage(:,:,2) = I(:,:,2).*uint8(mask);
croppedImage(:,:,3) = I(:,:,3).*uint8(mask);
Here is a bonus method with inpolygon if you want to crop arbitrary shapes:
% Load image
RGB = imread('peppers.png');
%Convert to 2D to create mask
GRAY = rgb2gray(RGB);
imageSize = size(GRAY);
ci = [250, 300, 100]; % center and radius of circle ([c_row, c_col, r])
%Create circle
h = viscircles(ci(1:2),ci(3));
c = h.Children(1).XData(1:end-1);
r = h.Children(2).YData(1:end-1);
% Create grid for mask
[C,R] = meshgrid(1:imageSize(2),1:imageSize(1));
%Find pts inside of circle
mask = inpolygon(R,C,r,c);
%Crop
croppedImage = uint8(zeros(imageSize));
croppedImage(:,:,1) = RGB(:,:,1).*uint8(mask);
croppedImage(:,:,2) = RGB(:,:,2).*uint8(mask);
croppedImage(:,:,3) = RGB(:,:,3).*uint8(mask);
imshow(croppedImage);

  0 Comments

Sign in to comment.


Image Analyst
Image Analyst on 27 Oct 2018
Try this to copy a circular mask/roi region from image 1 and then paste it onto the same location of image 2:
% Read first image.
rgbImage1 = imread('peppers.png');
[rows, columns, numberOfColorChannels] = size(rgbImage1);
subplot(2, 2, 1);
imshow(rgbImage1);
axis('on', 'image');
title('rgbImage1', 'FontSize', 20);
% Get the second image - should be the same size as rgbImage1.
rgbImage2 = imread('coloredChips.png');
rgbImage2 = imresize(rgbImage2, [rows, columns]);
subplot(2, 2, 2);
imshow(rgbImage2);
axis('on', 'image');
title('rgbImage2', 'FontSize', 20);
% Make the circle mask.
imageSize = size(rgbImage1);
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 = (xx.^2 + yy.^2) < ci(3)^2;
subplot(2, 2, 3);
imshow(mask);
axis('on', 'image');
title('Mask', 'FontSize', 20);
% Get the individual color channels
% Extract the individual red, green, and blue color channels.
redChannel1 = rgbImage1(:, :, 1);
greenChannel1 = rgbImage1(:, :, 2);
blueChannel1 = rgbImage1(:, :, 3);
% For the second one, let's use the new imsplit().
% It's in R2018b. If you don't have it, use code like the above.
[redChannel2, greenChannel2, blueChannel2] = imsplit(rgbImage2);
% Paste the image from the circle region of rgbImage1 onto rgbImage2 in just the circle region.
redChannel2(mask) = redChannel1(mask);
greenChannel2(mask) = greenChannel1(mask);
blueChannel2(mask) = blueChannel1(mask);
% Recombine separate color channels into a single, true color RGB image.
rgbImage2 = cat(3, redChannel2, greenChannel2, blueChannel2);
% Display it.
subplot(2, 2, 4);
imshow(rgbImage2);
axis('on', 'image');
title('Image 1 pasted onto image 2 only within mask', 'FontSize', 20);

  0 Comments

Sign in to comment.

Sign in to answer this question.