How can I automatically crop only the region of face and neck from the front view and side view images of a person?
5 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Shreyansh Dubey
am 5 Aug. 2018
Kommentiert: Shreyansh Dubey
am 6 Aug. 2018
I have been able to convert the whole image into a binary image and do my processing further on the image but i specifically want to do something with the neck of a person. I have 30 people in my data set, I have to have a universal code that works for all 30 people's image in one go, I have been able to do everything just I want an automatic method in which I feed in the binary images of side view and front view of the person and it either returns me the cropped face+neck part or stores the cropped portion in some directory. Here's the code where I am manually cropping the image and going further with processing.
if true
file2 = 'Dilfr.jpg';
file2r = imread(file2);
f2 = rgb2gray(file2r);
f3 = imbinarize(f2,'adaptive');
imcrop(f3); %%%I need an automatic replacement here
f4 = 'dcrop2.jpg';
F1 = imread(f4);
F2 = im2bw(F1);
filled = imfill(F2,'holes');
holes = filled & ~F2;
bigholes = bwareaopen(holes, 800);
F3 = bigholes;
figure,
imshow(F3);
end
3 Kommentare
Akzeptierte Antwort
Image Analyst
am 6 Aug. 2018
Bearbeitet: Image Analyst
am 6 Aug. 2018
Try this:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
%===============================================================================
% Read in gray scale demo image.
folder = pwd; % Determine where demo folder is (works with all versions).
baseFileName = 'dilfr.JPG';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(rgbImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
% grayImage = rgb2gray(rgbImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
grayImage = rgbImage(:, :, 2); % Take green channel.
else
grayImage = rgbImage; % It's already gray scale.
end
% Now it's gray scale with range of 0 to 255.
% Display the image.
subplot(2, 3, 1);
imshow(grayImage, []);
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
%------------------------------------------------------------------------------
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% Show the histogram
subplot(2, 3, 2);
[counts, grayLevels] = histcounts(grayImage(:));
counts(counts == max(counts)) = 0; % Suppress spike
bar(grayLevels(1:end-1), counts);
grid on;
title('Histogram of Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Median Filter to get rid of seams in wall.
windowSize = 11;
mfImage = medfilt2(grayImage, [windowSize, windowSize]);
% Display the image.
subplot(2, 3, 3);
imshow(mfImage, []);
title('Median Filtered Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
windowSize = 13;
sdImage = stdfilt(mfImage, ones(windowSize));
% Display the image.
subplot(2, 3, 4);
imshow(sdImage, []);
title('Standard Deviation Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
% Show the histogram
subplot(2, 3, 5);
[counts, grayLevels] = histcounts(sdImage(:));
counts(counts == max(counts)) = 0; % Suppress spike
bar(grayLevels(1:end-1), counts);
grid on;
title('Histogram of Standard Deviation Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Binarize the image
binaryImage = sdImage >= 25;
% Remove blobs touching border.
binaryImage = imclearborder(binaryImage);
% Take largest blob
binaryImage = bwareafilt(binaryImage, 1);
% Display the image.
subplot(2, 3, 6);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
% Get widths as a function of row
widths = zeros(rows, 1);
for row = 1 : rows
col1 = find(binaryImage(row, :), 1, 'first');
col2 = find(binaryImage(row, :), 1, 'last');
if ~isempty(col1)
widths(row) = col2 - col1 + 1;
end
end
figure
subplot(2, 1, 1);
plot(widths, 'b-', 'LineWidth', 2);
xlabel('Row', 'FontSize', fontSize);
ylabel('Width', 'FontSize', fontSize);
% Find valleys byinverting and finding peaks
[peakValues, indexes] = findpeaks(-widths);
peakValues = -peakValues; % Negate to flip over.
grid on;
hold on;
plot(indexes, peakValues, 'r+', 'MarkerSize', 12, 'LineWidth', 2);
% The neck is the first peak.
neckRow = indexes(1);
% Display the original image again.
subplot(2, 1, 2);
imshow(grayImage, []);
axis('on', 'image');
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
% Put a line up over the neck.
hold on;
line(xlim, [neckRow, neckRow], 'Color', 'r', 'LineWidth', 2);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
3 Kommentare
Image Analyst
am 6 Aug. 2018
As you scan down the lines in the loop, fill in the binary image from left to right:
binaryImage(row, col1:col2) = true;
Then, after you have determined the neck row, erase the binary image just from the neck down.
binaryImage(neckRow+1:end, :) = false;
Then call regionprops() and ask for centroid.
props = regionprops(binaryImage, 'Centroid');
Then make up a rectangle array using the centroid and a predetermined size that you want for the head such that it's the right size and centered on the centroid.
width = 75; % Whatever.
height = 80; % Whatever.
xLeft = props.Centroid(1) - width/2;
yTop = props.Centroid(2) - height/2;
croppingRectangle = [xLeft, yTop, width, height];
Then call imcrop() on the original gray scale image.
croppedImage = imcrop(grayImage, cropppingRectangle);
Pretty easy but let us know if you run into problems.
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Image Processing Toolbox finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!