cropping manually and automatic using matlab

6 views (last 30 days)
i want to seperate every scene in the comic, but the problem is not all of the scene are rectangle and there are so many details.
can u guys tell me the way to cropping manually or automatic after edge detection? and what the first thing i have to do before edge detection?
thanks..
  6 Comments
shara
shara on 7 Jul 2012
then i'm gonna change the image, what about this http://imageshack.us/f/13/hiltunenpetri.gif/ there's a dialog that's not fully in the box..
Image Analyst
Image Analyst on 7 Jul 2012
Yes. that would make them connected but you can try to do imopen() to break that connection.

Sign in to comment.

Answers (3)

Image Analyst
Image Analyst on 8 Jul 2012
Edited: Image Analyst on 8 Jul 2012
Do you still need the manual method? I'd use rbbox or imrect - see the help for examples. For the automatic one, I probably did too much for you, but here is the code for the "depressingcomic" image.
% function to crop out panels of a cartoon/comic.
clc;
clearvars;
close all;
workspace;
fontSize = 14;
% Read in a standard MATLAB color demo image.
folder = 'C:\Users\shara\Documents\Temporary';
baseFileName = 'depressingcomicweek3cya.jpg';
fullFileName = fullfile(folder, baseFileName);
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 3, 1);
imshow(rgbImage);
title('Original Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Erase copyright.
rgbImage(552:end, 202:430, :) = 255;
% Erase title.
rgbImage(1:25, :, :) = 255;
% Display the color image.
subplot(2, 3, 2);
imshow(rgbImage);
title('Copyright and Title Erased', 'FontSize', fontSize);
% Binarize to find black pixels
% Find where either red, green, or blue channel is dark.
thresholdValue = 55;
binaryImage = rgbImage(:,:, 1) < thresholdValue | rgbImage(:,:, 2) < thresholdValue | rgbImage(:,:, 3) < thresholdValue;
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage);
title('Binary Image', 'FontSize', fontSize);
% Fill the image
filledImage = imfill(binaryImage, 'holes');
% Display the image.
subplot(2, 3, 4);
imshow(filledImage);
title('Filled Binary Image', 'FontSize', fontSize);
drawnow;
% Label the image - find connected components.
[labeledImage numberOfBlobs] = bwlabel(filledImage);
% Get bounding boxes for all the regions.
measurements = regionprops(labeledImage, 'BoundingBox');
% Create colors for all the boxes.
boxColors = lines(numberOfBlobs);
% Fill in the bounding boxes to mask the "broken" panels.
for k = 1 : numberOfBlobs
x1 = measurements(k).BoundingBox(1);
y1 = measurements(k).BoundingBox(2);
width = measurements(k).BoundingBox(3);
height = measurements(k).BoundingBox(4);
x2 = x1 + width;
y2 = y1 + height;
% Plot the boxes in different colors in a separate subplot.
subplot(2, 3, 5);
hold on;
set(gca, 'ydir', 'reverse');
thisColor = boxColors(k, :);
rectangle('Position', [x1 y1 width height], 'EdgeColor', thisColor);
drawnow;
title('All the Bounding Boxes', 'FontSize', fontSize);
x1 = ceil(x1); % Get rid of the 0.5
y1 = ceil(y1); % Get rid of the 0.5
x2 = floor(x2); % Get rid of the 0.5
y2 = floor(y2); % Get rid of the 0.5
filledImage(y1:y2, x1:x2) = true;
% Display the image.
subplot(2, 3, 6);
imshow(filledImage);
title('Filled Binary Image', 'FontSize', fontSize);
end
% Call bwlabel again. This time there shoudl be 5 objects.
[labeledImage numberOfBlobs] = bwlabel(filledImage);
% Get bounding boxes for all the regions.
measurements = regionprops(labeledImage, 'BoundingBox');
% Inform user.
message = sprintf('We have now found the %d panels.\nNow we will crop them out', numberOfBlobs);
uiwait(msgbox(message));
% Create a new figure for this.
figure;
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Crop out the individual panels.
for k = 1 : numberOfBlobs
x1 = measurements(k).BoundingBox(1);
y1 = measurements(k).BoundingBox(2);
width = measurements(k).BoundingBox(3);
height = measurements(k).BoundingBox(4);
subImage = imcrop(rgbImage, [x1 y1 width height]);
% Display the image.
subplot(2, 3, k);
imshow(subImage);
caption = sprintf('Panel #%d', k);
title(caption, 'FontSize', fontSize);
if k < numberOfBlobs
message = sprintf('That was panel #%d.\nDo you want to continue and show panel #%d?', k, k+1);
% Inform user - allow to bail out if desired.
button = questdlg(message, 'Continue?', 'Yes', 'No', 'Yes');
drawnow; % Refresh screen to get rid of dialog box remnants.
if strcmpi(button, 'No')
break;
end
end
end
msgbox('Thank you ImageAnalyst!');
  13 Comments
Image Analyst
Image Analyst on 30 Jul 2012
I don't know, especially without seeing the line of code it refers to. Why don't you set a breakpoint there and look at the values of all the indexes on that line, as well as the size of the array. That will tell you which index is out of range.

Sign in to comment.


Image Analyst
Image Analyst on 7 Jul 2012
Just crop it.
width = col1 - col2 + 1;
height = row2 - row1 + 1;
onePanel = imcrop(originalImage, [row1 col1 width height]);
Where col1, row1, col2, and row2 are is obviously a judgement call - you and I might not agree on where they are.
  9 Comments
Image Analyst
Image Analyst on 8 Jul 2012
Can we assume that the copyright box will be in the same location for all your images? Because that's the only thing that would complicate the algorithm. Otherwise it's really simple, but that copyright connects the bottom three panels together. If I can assume that it will always be in the same place, I can erase it, threshold, fill, find bounding boxes, mask, then regionprops again to find bounding boxes again, and it will get the rectangular panels. But if the copyright box is sometimes there and sometimes not, or it's in different locations, then it would be a much more complicated algorithm.
shara
shara on 8 Jul 2012
i think i'm not gonna use the copyright, maybe i'll erase it. so what step should i do? could u give me the example code? thanks before..

Sign in to comment.


Ryan
Ryan on 8 Jul 2012
Edited: Ryan on 8 Jul 2012
Manual method:
scenenum = input('Please enter the number of scenes you wish to crop: ')
for m = 1:scenenum
mask = roipoly(Img);
segment{m} = immultiply(Img,mask);
Img = immultiply(Img,~mask);
figure, imshow(segment{m})
end
  12 Comments
Walter Roberson
Walter Roberson on 29 Jul 2012
7.8... that's R2009a if I remember correctly.
We have not been told what the error message is. Possibly it is complaining that the two inputs are of different classes.
Image Analyst
Image Analyst on 29 Jul 2012
This is not what shara wants to do anyway, which is cropping. This would mask, not crop. Masking blackens inside or outside some area, while cropping extracts the bounding box of the region into a new smaller image.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!