Crop a circle from an image and put it on another image
19 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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 comentarios
Respuestas (2)
jonas
el 27 de Oct. de 2018
Editada: jonas
el 27 de Oct. de 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 comentarios
Image Analyst
el 27 de Oct. de 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);
8 comentarios
Image Analyst
el 18 de Nov. de 2022
Editada: Image Analyst
el 18 de Nov. de 2022
Sure, try it! Just get a coordinate of one circle in the input and another coordinate in the output image. Just do one circle at a time instead of all 50 at once. Start a new question if you still need help.
Anand Ra
el 18 de Nov. de 2022
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!