Cropping DICOM image to exact size

20 views (last 30 days)
I have a large batch of DICOM images that I'm pre-processing for use in a convolutional neural network (for classification). Part of this pre-processing involves segmentating the images to a smaller exact size around the area of interest in the scan, keeping all of these segmentations the same size. Essentially, I want to just crop a 128x128 square out of each image, manually selecting where this square is each time.
It seems like a simple enough thing to do but I'll be working with a lot of images so I'm really just looking for suggestions and pointers to help me develop a method to do this efficiently.
Thanks in advance for your help!

Accepted Answer

Image Analyst
Image Analyst on 13 Feb 2018
OK, 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 = 25;
%===============================================================================
% Get the name of the image the user wants to use.
% Have user browse for a file, from a specified "starting folder."
% For convenience in browsing, set a starting folder from which to browse.
startingFolder = pwd;
if ~exist(startingFolder, 'dir')
% If that folder doesn't exist, just start in the current folder.
startingFolder = pwd;
end
% Get the name of the file that the user wants to use.
defaultFileName = fullfile(startingFolder, '*.*');
[baseFileName, folder] = uigetfile(defaultFileName, 'Select a file');
if baseFileName == 0
% User clicked the Cancel button.
return;
end
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
%===============================================================================
% Read in a demo image.
grayImage = 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(grayImage)
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(grayImage);
% 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 = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
subplot(1, 2, 1);
imshow(grayImage, []);
axis on;
axis image;
caption = sprintf('Original Gray Scale Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo();
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% 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 Mark Hayworth', 'NumberTitle', 'Off')
drawnow;
uiwait(msgbox('Drag out a 128x128 box'));
% Let user draw the box.
k = waitforbuttonpress;
point1 = get(gca,'CurrentPoint'); % button down detected
finalRect = rbbox; % return figure units
point2 = get(gca,'CurrentPoint'); % button up detected
point1 = point1(1,1:2); % extract x and y
point2 = point2(1,1:2);
x1 = point1(1);
y1 = point1(2);
x2 = point2(1);
y2 = point2(2);
% Find the coordinates of the box.
xUserBox = [x1, x2, x2, x1, x1];
yUserBox = [y1, y1, y2, y2, y1];
% The box from rbbox() disappears after drawing.
% Redraw what they drew.
hold on
axis manual
plot(xUserBox, yUserBox, 'r-', 'LineWidth', 2); % Draw box.
% Now we need to get a 128x128 box centered at that location.
% Compute the center
xCenter = (x1 + x2)/2; % Get average.
yCenter = (y1 + y2)/2; % Get average.
plot(xCenter, yCenter, 'r+', 'MarkerSize', 30, 'LineWidth', 2); % Plot cross at center.
% Get box edges for a 128x128 box centered at the center of the box that they drew.
x1 = round(xCenter - 64)
y1 = round(yCenter - 64)
x2 = x1 + 127
y2 = y1 + 127
% Find the coordinates of the box.
xBox128 = [x1, x2, x2, x1, x1];
yBox128 = [y1, y1, y2, y2, y1];
% Draw the 128x128 box
plot(xBox128, yBox128, 'b-', 'LineWidth', 2);
% Display the image.
croppedImage = grayImage(y1:y2, x1:x2);
[rows, columns, numColors] = size(croppedImage) % Show values just to make sure.
subplot(1, 2, 2);
imshow(croppedImage, []);
axis on;
title('Cropped 128x128 Image', 'FontSize', fontSize, 'Interpreter', 'None');
  1 Comment
Cameron Harris
Cameron Harris on 16 Feb 2018
Thanks so much for the detailed answer, its a real help! Apologies for the delay in reply I've been off sick for the last couple of days.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 13 Feb 2018
I'd probably call rbbox() and then determine the center of what they drew, then find the edges by subtracting and adding 14 to the center of the box (rounding the result of course). Then use indexing to extract the cropped region.
Here's a snippet where I use rbbox() in one of my demos:
k = waitforbuttonpress;
point1 = get(gca,'CurrentPoint'); % button down detected
finalRect = rbbox; % return figure units
point2 = get(gca,'CurrentPoint'); % button up detected
point1 = point1(1,1:2); % extract x and y
point2 = point2(1,1:2);
p1 = min(point1,point2); % calculate locations
offset = abs(point1-point2); % and dimensions
% Find the coordinates of the box.
xCoords = [p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1) p1(1)];
yCoords = [p1(2) p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2)];
x1 = round(xCoords(1));
x2 = round(xCoords(2));
y1 = round(yCoords(5));
y2 = round(yCoords(3));
width = x2-x1;
height = y2-y1;
% The box from rbbox() disappears after drawing, so redraw the box over the image.
hold on
axis manual
plot(xCoords, yCoords, 'b-'); % redraw in dataspace units
You'll need to do it slightly differently to make sure you have 128x128 cropped regions. If you can't figure it out, write back.
  1 Comment
Cameron Harris
Cameron Harris on 13 Feb 2018
Thanks for the answer and the suggestion of using the rubberband box function - it definitely appears to be the right method to use here. The issue I'm finding is fixing the size of the box using rbbox. I've been experimenting with trying to specify the height and width of initialRect so that rbbox pops up with the correct size of box when point1 is selected but I'm not having any success. Is this along the right lines?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!