Is it possible to procedurally remove things from an engineering drawing?

42 views (last 30 days)
I have been working on a post processing software for a few months for a robotics system my company makes. It does a lot of different things and is now being rolled out to our customers for use, which is exciting for me. My company makes a few different types of robots, one of them is very different than the others. To give a bit of context before getting to my question:
One of our robots does hull cleaning and inspection autonomously. When the vehicle is attached to a hull, the coordinate system is now relative to the ship, meaning the heading of the vehicle is relative to the Bow where 0 degrees is pointing towards the bow, 180 is pointed stern. "Latitude" is relative to the bottom where 0 degrees is at the keel and 90 degrees is at the waterline. "Longitude" is the distance from the centerline of the ship, where 180 is at the bow, and -180 is at the stern. Its a weird system but it doesnt matter where we are in the world, it only matters where we are on the ship.
Im trying to improve my app to work with this other robotics system, for all of our other robots we use a regular coordinate system with regular lat and long. When the user plots the data it does so over a satellite basemap, it looks great. When a user of our hull cleaning robot plots the data we typically do it over a 2D "folded out" image of the ship. Right now we have to do this by hand and its time consuming. The customer, who ever is hiring us to clean their ship, will provide us with an engineering drawing of the vessel, but there is a lot of stuff in the document we dont want to be included in the final product. Usually our operators use MS Paint or Adobe Illustrator to remove all the extra stuff, and they are left with a profile of the port, starboard, and top down veiw of the vessel, then we put it in QGIS and plot the points on top. Following this we take a screenshot and edit everything for a final product. Its time consuming and exhausting.
So heres my question. How can I get matlab to remove all the extra stuff for me? The two images I attached is what the engineering drawings typically look like vs what we use for our final product. I have the imaging processing toolbox and im trying to find a way to remove the extra stuff. the problem is its always a little different, sometimes the ships are much bigger than others. Any help or advice would be very much appreciated!

Answers (3)

Star Strider
Star Strider on 21 Jan 2026 at 18:59
Moved: Star Strider on 22 Jan 2026 at 5:31
After experimenting a bit, it would probably be necessary for you to use bwtraceboundary or something similar and do this manually.
  3 Comments
Star Strider
Star Strider on 21 Jan 2026 at 21:22
Edited: Star Strider on 22 Jan 2026 at 5:35
My pleasure!
If it solved your problem, I should have posted it as an answer.
Oh, well ...
EDIT -- (22 Jan 2026 at 05:35)
Moved here.
Image Analyst
Image Analyst on 25 Jan 2026 at 14:34
The problem is bwtraceboundary will get outlines of all the lines that touch the hull even though they're not part of the hull and just clutter, gridlines, etc. That's for the solid lines. For the dotted line hull you'd have to run it on every single dot.

Sign in to comment.


Image Analyst
Image Analyst on 22 Jan 2026 at 5:11
Unless you can get some standardization, which I'd doubt, it looks like the best option would be to use Photoshop and paint out the parts you don't want. Each ship will have different engineering drawings with all kinds of junk on there and it would be difficult to automatically know which lines (solid, dashed, or dotted) are the ones for the ship boundary and which are just words, scales, or other clutter.
If I had to I'd probably attack it like this.
Do a closing with imclose to connect dotted lines (like ship's water line). Hopefully the ship perimeter will be closed.
Then call imfill to fill inside. Hopefully this will leave you with the interior of the ship solid.
Then use imopen to chop off tendrils like clutter form words, lines, scales, etc. that touch the ship's boundary.
Then call bwareafilt to extract the largest blob only. Hopefully that's the solid ship.
Then call bwperim to get the outline/perimeter of the solid ship.
That said, I doubt it would give you perfect results. However it might clean up a lot of stuff so that the manual editing done in Photoshop will be less.

Image Analyst
Image Analyst on 25 Jan 2026 at 17:22
I made a stab at trying to get the perimeters. It's not perfect but it may cut down on how much is left that you manually have to paint away.
% Demo by Image Analyst
% Initialization steps:
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 = 18;
%--------------------------------------------------------------------------------------------------------
% READ IN FIRST IMAGE
folder = pwd;
baseFileName = "ship hull.png";
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~isfile(fullFileName)
% 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
% Read in image file.
grayImage = imread(fullFileName);
% Get size
[rows, columns, numberOfColorChannels] = size(grayImage)
rows = 883
columns = 1866
numberOfColorChannels = 3
% Get gray scale version of it.
if numberOfColorChannels == 3
grayImage = grayImage(:, :, 1); % Take red channel.
end
% Display the image.
subplot(2, 2, 1);
% Use imadjust just to expand the dynamic range of the display
% but it's not changing the grayImage pixel values in the variable.
imshow(imadjust(grayImage), []);
axis('on', 'image');
impixelinfo;
caption = sprintf('Original image : %s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
g.Name = 'Demo by Image Analyst';
g.NumberTitle = 'off';
drawnow;
%--------------------------------------------------------------------------------------------------------
% The image is gray scale. Binarize it.
% Set initial threshold limits
lowThreshold = 0;
highThreshold = 128;
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% [lowThreshold, highThreshold] = threshold(40, 255, grayImage);
% Threshold the image to create a mask.
firstMask = grayImage >= lowThreshold & grayImage <= highThreshold;
%--------------------------------------------------------------------------------------------------------
% There is a white frame touching the edge of the image. Get rid of it.
% mask2 = imclearborder(firstMask); % Also gets rid of bottom hull, which touches border so don't use this.
mask2 = firstMask; % Initialize
widthToErase = 12; % Pixels.
mask2(1:widthToErase, :) = false; % Erase top edge
mask2(end-widthToErase : end, :) = false; % Erase bottom edge
mask2(:, 1:widthToErase) = false; % Erase left edge
mask2(:, end-widthToErase : end) = false; % Erase right edge
%--------------------------------------------------------------------------------------------------------
% Widen the mask.
se = strel('disk', 3); % Change 7 to whatever width you want.
firstMask = imdilate(mask2, se); % Widen the mask.
% Display the mask image.
subplot(2, 2, 2);
imshow(mask2);
axis('on', 'image');
impixelinfo;
title('Widened Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Now fill holes.
mask2 = imfill(firstMask, 'holes');
% Now there is still a lot of clutter so let's extract only the 3 largest blobs.
mask3 = bwareafilt(mask2, 3);
% Display the mask image.
subplot(2, 2, 3);
imshow(mask3);
axis('on', 'image');
impixelinfo;
title('Biggest 3 blobs', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get the outer perimeter only.
outputImage = bwperim(mask3);
% Display the final gray scale image.
subplot(2, 2, 4);
imshow(outputImage, []);
axis('on', 'image');
impixelinfo;
title('Final Perimeter Image', 'FontSize', fontSize, 'Interpreter', 'None');
% The image will be subsampled for display. Use the toolbar magnifying
% glass to zoom in and see the thin perimeters.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Products


Release

R2025b

Community Treasure Hunt

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

Start Hunting!