how to auto crop a image?
20 次查看(过去 30 天)
显示 更早的评论
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1537340/image.jpeg)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1537345/image.jpeg)
i need to crop these images from first one to second one ...ad i have so many images...please advise me!
3 个评论
DGM
2023-11-17
The core of the example below shows a very simplified method of removing the padding. The link also includes a comparison of other tools, though those are all FEX tools.
If it's only one image, consider that you can also just use imcrop() (or external software) to crop the image manually as you see fit. ... or you could even attach it and I'll crop it.
采纳的回答
Image Analyst
2023-11-19
编辑:Image Analyst
2023-11-19
Try this:
% Initialization steps.
clc; % Clear the command window.
format long g;
format compact;
fontSize = 20;
fileName = 'arian hoseini.png';
rgbImage = imread(fileName);
% Display original image
subplot(2, 1, 1);
imshow(rgbImage);
axis('on', 'image');
impixelinfo;
title('Original Image', 'FontSize', fontSize);
drawnow;
[r, g, b] = imsplit(rgbImage);
% Get mask of where pixels are pure white.
mask = (r == 255) & (g == 255) & (b == 255);
% Find where it's not pure white
mask = ~mask;
% Find where the row is not all white
verticalProfile = any(mask, 2);
% Find top row
topRow = find(verticalProfile, 1, 'first');
% Find bottom row
bottomRow = find(verticalProfile, 1, 'last');
% Find where the column is not all white
horizontalProfile = any(mask, 1);
% Find left column
leftColumn = find(horizontalProfile, 1, 'first');
% Find right column
rightColumn = find(horizontalProfile, 1, 'last');
% Extract/crop it
croppedImage = rgbImage(topRow:bottomRow, leftColumn:rightColumn, :);
% Display cropped image
subplot(2, 1, 2);
imshow(croppedImage); % Display it.
axis('on', 'image');
impixelinfo;
title('Cropped Image', 'FontSize', fontSize);
Attach an actual image file (not a screenshot) if it doesn't work.
2 个评论
Image Analyst
2023-11-23
Looks like it worked perfectly to me. @arian hoseini are you still alive? Did you even run the demo I took the time to create for you? Did it work for you?
If this Answer solves your original question, then could you please click the "Accept this answer" link to award the answerer with "reputation points" for their efforts in helping you? They'd appreciate it. Thanks in advance. 🙂 Note: you can only accept one answer (so pick the best one) but you can click the "Vote" icon for as many Answers as you want. Voting for an answer will also award reputation points.
更多回答(1 个)
DGM
2023-11-12
编辑:DGM
2023-11-12
I'm not sure if this is about a white border or (if that's the case) whether figure capture was the cause. That said, I'm getting ready to leave, so for sake of providing an interim attempt at solution, I'm going to make that assumption. In either case, this should reveal a method to remove the border. Again, if the cause is figure capture, following through with border removal should be discouraged.
% let's say we have an image (256x256x1, uint8)
A = imread('cameraman.tif');
% say we displayed it in a figure and captured the figure
% this could happen either programmatically (saveas(), print(), exportgraphics())
% or it could happen interactively via the figure or axes toolbars
imshow(A)
fname = 'junk.jpg';
saveas(gcf,fname) % don't do this
% now we have a screenshot that's been degraded:
% - the actual image area has been resized unpredictably
% with crude nearest-neighbor interpolation
% - some unpredictable amount of padding has been added
% - since we used JPG, the image content is further degraded
% - the image is no longer strictly grayscale
B = imread(fname);
% let's say we wanted to go ahead and "fix" the junk screenshot
% instead of going back and saving the image properly
mask = any(B<255,3);
% find ROI geometry
mkr = any(mask,2);
mkc = any(mask,1);
r1 = find(mkr,1,'first');
r2 = find(mkr,1,'last');
c1 = find(mkc,1,'first');
c2 = find(mkc,1,'last');
% crop original image to extents
B = B(r1:r2,c1:c2,:,:);
% resize cropped image to original geometry
B = imresize(B,size(A,1:2));
% collapse the screenshot back to gray, since that's what it was
B = im2gray(B);
% visualize the error caused by using a screenshot
errpreview = imfuse(A,B,'diff');
imshow(errpreview)
Note how much code it took to save and postprocess the screenshot. Compare that to how the image should be saved:
imwrite(A,'good.png') % one line
Of course, this assumes that A is properly-scaled for an image of its numeric class. If you have floating point data that's not unit-scale (i.e. not between 0-1), then it should be normalized based on whatever limiting values are appropriate for the given context.
If the cause for the border isn't figure capture, apologies for making that assumption, but understand that it's a very common pitfall. Either way, the above example demonstrates a simple method for removing strictly white borders.
See also:
2 个评论
DGM
2023-11-19
编辑:DGM
2023-11-20
Oh. I didn't notice you were running R2016b. That (seemingly obvious) functionality wasn't added to size() until R2019b.
% sz = [size(A,1) size(A,2)];
% B = imresize(B,sz);
That said, you shouldn't need to do that. That was just part of the comparison demo.
Consider the following image. It's impossible to see the border because of the awful white page background, but it has a white border.
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1543812/image.png)
Crop it.
% read the file (I/RGB)
inpict = imread('blah.png');
% create a mask where the image is not white
mask = any(inpict<255,3);
% find ROI geometry
mkr = any(mask,2);
mkc = any(mask,1);
r1 = find(mkr,1,'first');
r2 = find(mkr,1,'last');
c1 = find(mkc,1,'first');
c2 = find(mkc,1,'last');
% crop original image to extents
outpict = inpict(r1:r2,c1:c2,:,:);
% show the result
imshow(outpict,'border','tight')
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1543817/image.png)
Again, it's impossible to show the results on the forum unless I add extra padding to the image again. Either way, that should work so long as the border is strictly white, regardless of how many channels the image has.
For what it's worth, MIMT cropborder() works as well, and it would work even if the border isn't exactly white.
% read the file (I/RGB)
inpict = imread('blah.png');
% crop off any uniformly-colored border
% each side may have different width
outpict = cropborder(inpict,nan(1,4));
% show the result
imshow(outpict,'border','tight')
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1543817/image.png)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!