欢迎来到本博客❤️❤️
博主优势:博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。
⛳️座右铭:行百里者,半于九十。
本文目录如下:
目录
1 概述
2 运行结果
3参考文献
4 Matlab代码实现
1 概述
【图像分割】图像检测(分割、特征提取)、各种特征(面积等)的测量和过滤
本文提供了一个适合初学者的教程,旨在演示图像检测(分割、特征提取)以及各种特征(如面积)的测量和过滤(只提取某些对象)。
首先,该教程介绍了如何找到图像中的所有对象(硬币),然后根据指定的直径过滤结果,筛选出特定直径的对象。通过一个简单的示例,展示了阈值处理、标记和区域属性的基本概念。
对于那些刚开始接触 MATLAB 图像处理功能的同学来说,这个教程是一个很好的起点。在他们深入学习更复杂的算法之前,可以通过这个教程加深对基本概念和技术的理解。
为了完成这个教程,需要安装图像处理工具箱,因为它演示了该工具箱提供的某些功能。同时,教程使用了工具箱自带的一个名为“硬币”的示例图像作为演示对象。
该教程的优点在于,它提供了一种直观和实用的方法,帮助初学者理解如何使用 MATLAB 对图像进行处理和分析。通过学习如何进行图像分割、特征提取和过滤,读者将受益于这些基本概念,并能够应用它们解决更为复杂的图像处理问题。这个教程对于那些有兴趣进一步探索图像处理领域的学生、研究人员和工程师来说,都是一个很好的起点。
2 运行结果
部分代码:
% Read in a standard MATLAB demo image of coins (US nickles and dimes, which are 5 cent and 10 cent coins).This image ships with MATLAB.baseFileName = 'coins.png';folder = fileparts(which(baseFileName)); % Determine where demo folder is (works with all versions).fullFileName = fullfile(folder, baseFileName);fprintf('Full File Name = "%s".\n', fullFileName);if ~exist(fullFileName, 'file')% It doesn't exist in the current folder.% Look on the search path.if ~exist(baseFileName, 'file')% It doesn't exist on the search path either.% Alert user that we can't find the image.warningMessage = sprintf('Error: the input image file\n%s\nwas not found.\nClick OK to exit the demo.', fullFileName);uiwait(warndlg(warningMessage));fprintf(1, 'Finished running BlobsDemo.m.\n');return;end% Found it on the search path.Construct the file name.fullFileName = baseFileName; % Note: don't prepend the folder.end% If we get here, we should have found the image file.originalImage = imread(fullFileName);% Check to make sure that it is grayscale, just in case the user substituted their own image.[rows, columns, numberOfColorChannels] = size(originalImage);if numberOfColorChannels > 1promptMessage = sprintf('Your image file has %d color channels.\nThis demo was designed for grayscale images.\nDo you want me to convert it to grayscale for you so you can continue" /> thresholdValue; % Bright objects will be chosen if you use >.% ========== IMPORTANT OPTION ============================================================% Use < if you want to find dark objects instead of bright objects.% binaryImage = originalImage < thresholdValue; % Dark objects will be chosen if you use 150) & (allBlobIntensities < 220);allowableAreaIndexes = allBlobAreas < 2000; % Take the small objects.% Now let's get actual indexes, rather than logical indexes, of thefeatures that meet the criteria.% for example [1, 4, 5, 7, .....] to continue using the example from above.keeperIndexes = find(allowableIntensityIndexes & allowableAreaIndexes);% Extract only those blobs that meet our criteria, and% eliminate those blobs that don't meet our criteria.% Note how we use ismember() to do this.Result will be an image - the same as labeledImage but with only the blobs listed in keeperIndexes in it.keeperBlobsImage = ismember(labeledImage, keeperIndexes);% Re-label with only the keeper blobs kept.labeledDimeImage = bwlabel(keeperBlobsImage, 8); % Label each blob so we can make measurements of it% Now we're done.We have a labeled image of blobs that meet our specified criteria.subplot(3, 3, 7);imshow(labeledDimeImage, []);axis image;title('"Keeper" blobs (3 brightest dimes in a re-labeled image)', 'FontSize', captionFontSize);elapsedTime = toc;fprintf('Blob detection and measurement took %.3f seconds.\n', elapsedTime)%------------------------------------------------------------------------------------------------------------------------------------------------------% Plot the centroids in the overlay above the original image in the upper left axes.% Dimes will have a red cross, nickels will have a blue X.message = sprintf('Now I will plot the centroids over the original image in the upper left.\nPlease look at the upper left image.');reply = questdlg(message, 'Plot Centroids?', 'OK', 'Cancel', 'Cancel');% Note: reply will = '' for Upper right X, 'OK' for OK, and 'Cancel' for Cancel.if strcmpi(reply, 'Cancel')return;endsubplot(3, 3, 1);hold on; % Don't blow away image.for k = 1 : numberOfBlobs % Loop through all keeper blobs.% Identify if blob #k is a dime or nickel.itsADime = allBlobAreas(k) 2000);% Take the larger objects.% Note how we use ismember to select the blobs that meet our criteria.Get a binary image with only nickel regions present.nickelBinaryImage = ismember(labeledImage, keeperIndexes);% Let's get the nickels from the original grayscale image, with the other non-nickel pixels blackened.% In other words, we will create a "masked" image.maskedImageNickel = originalImage; % Simply a copy at first.maskedImageNickel(~nickelBinaryImage) = 0;% Set all non-nickel pixels to zero.subplot(3, 3, 9);imshow(maskedImageNickel, []);axis image;title('Only the nickels from the original image', 'FontSize', captionFontSize);%------------------------------------------------------------------------------------------------------------------------------------------------------% WE'RE BASICALLY DONE WITH THE DEMO NOW.elapsedTime = toc;% Alert user that the demo is done and give them the option to save an image.message = sprintf('Done making measurements of the features.\n\nElapsed time = %.2f seconds.', elapsedTime);message = sprintf('%s\n\nCheck out the figure window for the images.\nCheck out the command window for the numerical results.', message);message = sprintf('%s\n\nDo you want to save the pseudo-colored image?', message);reply = questdlg(message, 'Save image?', 'Yes', 'No', 'No');% Note: reply will = '' for Upper right X, 'Yes' for Yes, and 'No' for No.if strcmpi(reply, 'Yes')% Ask user for a filename.FilterSpec = {'*.PNG', 'PNG Images (*.png)'; '*.tif', 'TIFF images (*.tif)'; '*.*', 'All Files (*.*)'};DialogTitle = 'Save image file name';% Get the default filename.Make sure it's in the folder where this m-file lives.% (If they run this file but the cd is another folder then pwd will show that folder, not this one.thisFile = mfilename('fullpath');[thisFolder, baseFileName, ext] = fileparts(thisFile);DefaultName = sprintf('%s/%s.tif', thisFolder, baseFileName);[fileName, specifiedFolder] = uiputfile(FilterSpec, DialogTitle, DefaultName);if fileName ~= 0% Parse what they actually specified.[folder, baseFileName, ext] = fileparts(fileName);% Create the full filename, making sure it has a tif filename.fullImageFileName = fullfile(specifiedFolder, [baseFileName '.tif']);% Save the labeled image as a tif image.imwrite(uint8(coloredLabels), fullImageFileName);% Just for fun, read image back into the imtool utility to demonstrate that tool.tifimage = imread(fullImageFileName);imtool(tifimage, []);endend%------------------------------------------------------------------------------------------------------------------------------------------------------% OPTIONAL : CROP EACH COIN OUT TO A SEPARATE SUB-IMAGE ON A NEW FIGURE.message = sprintf('Would you like to crop out each coin to individual images?');reply = questdlg(message, 'Extract Individual Images?', 'Yes', 'No', 'Yes');% Note: reply will = '' for Upper right X, 'Yes' for Yes, and 'No' for No.if strcmpi(reply, 'Yes')% Maximize the figure window.hFig2 = figure;% Create a new figure window.hFig2.Units = 'normalized';hFig2.WindowState = 'maximized'; % Go to full screen.hFig2.NumberTitle = 'off'; % Get rid of "Figure 1"hFig2.Name = 'Demo by Image Analyst'; % Put this into title bar.for k = 1 : numberOfBlobs% Loop through all blobs.% Find the bounding box of each blob.thisBlobsBoundingBox = props(k).BoundingBox;% Get list of pixels in current blob.% Extract out this coin into it's own image.subImage = imcrop(originalImage, thisBlobsBoundingBox);% Determine if it's a dime (small) or a nickel (large coin).if props(k).Area > 2200coinType = 'nickel';elsecoinType = 'dime';end% Display the image with informative caption.subplot(3, 4, k);imshow(subImage);caption = sprintf('Coin #%d is a %s.\nDiameter = %.1f pixels\nArea = %d pixels', ...k, coinType, blobECD(k), props(k).Area);title(caption, 'FontSize', textFontSize);end%------------------------------------------------------------------------------------------------------------------------------------------------------% Display the MATLAB "peaks" logo.logoSubplot = subplot(3, 4, 11:12);caption = sprintf('A MATLAB Tutorial by ImageAnalyst');text(0.5,1.15, caption, 'Color','r', 'FontSize', 18, 'FontWeight','b', 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle') ;positionOfLowerRightPlot = get(logoSubplot, 'position');L = 40*membrane(1,25);logoax = axes('CameraPosition', [-193.4013, -265.1546, 220.4819],...'Box', 'off', ...'CameraTarget',[26, 26, 10], ...'CameraUpVector',[0, 0, 1], ...'CameraViewAngle',9.5, ...'DataAspectRatio', [1, 1, .9],...'Position', positionOfLowerRightPlot, ...'Visible','off', ...'XLim',[1, 51], ...'YLim',[1, 51], ...'ZLim',[-13, 40], ...'parent', gcf);axis(logoSubplot, 'off');s = surface(L, ...'EdgeColor','none', ...'FaceColor',[0.9, 0.2, 0.2], ...'FaceLighting','phong', ...'AmbientStrength',0.3, ...'DiffuseStrength',0.6, ...'Clipping','off',...'BackFaceLighting','lit', ...'SpecularStrength',1, ...'SpecularColorReflectance',1, ...'SpecularExponent',7, ...'Tag','TheMathWorksLogo', ...'parent',logoax);l1 = light('Position',[40, 100, 20], ...
% OPTIONAL : CROP EACH COIN OUT TO A SEPARATE SUB-IMAGE ON A NEW FIGURE.
message = sprintf(‘Would you like to crop out each coin to individual images?’);
reply = questdlg(message, ‘Extract Individual Images?’, ‘Yes’, ‘No’, ‘Yes’);
% Note: reply will = ” for Upper right X, ‘Yes’ for Yes, and ‘No’ for No.
if strcmpi(reply, ‘Yes’)
% Maximize the figure window.
hFig2 = figure; % Create a new figure window.
hFig2.Units = ‘normalized’;
hFig2.WindowState = ‘maximized’; % Go to full screen.
hFig2.NumberTitle = ‘off’; % Get rid of “Figure 1”
hFig2.Name = ‘Demo by Image Analyst’; % Put this into title bar.
for k = 1 : numberOfBlobs% Loop through all blobs.
% Find the bounding box of each blob.
thisBlobsBoundingBox = props(k).BoundingBox; % Get list of pixels in current blob.
% Extract out this coin into it’s own image.
subImage = imcrop(originalImage, thisBlobsBoundingBox);
% Determine if it’s a dime (small) or a nickel (large coin).
if props(k).Area > 2200
coinType = ‘nickel’;
else
coinType = ‘dime’;
end
% Display the image with informative caption.
subplot(3, 4, k);
imshow(subImage);
caption = sprintf(‘Coin #%d is a %s.\nDiameter = %.1f pixels\nArea = %d pixels’, …
k, coinType, blobECD(k), props(k).Area);
title(caption, ‘FontSize’, textFontSize);
end
%——————————————————————————————————————————————————
% Display the MATLAB “peaks” logo.
logoSubplot = subplot(3, 4, 11:12);
caption = sprintf(‘A MATLAB Tutorial by ImageAnalyst’);
text(0.5,1.15, caption, ‘Color’,’r’, ‘FontSize’, 18, ‘FontWeight’,’b’, ‘HorizontalAlignment’, ‘center’, ‘VerticalAlignment’, ‘middle’) ;
positionOfLowerRightPlot = get(logoSubplot, ‘position’);
L = 40*membrane(1,25);
logoax = axes(‘CameraPosition’, [-193.4013, -265.1546, 220.4819],…
‘Box’, ‘off’, …
‘CameraTarget’,[26, 26, 10], …
‘CameraUpVector’,[0, 0, 1], …
‘CameraViewAngle’,9.5, …
‘DataAspectRatio’, [1, 1, .9],…
‘Position’, positionOfLowerRightPlot, …
3参考文献
文章中一些内容引自网络,会注明出处或引用为参考文献,难免有未尽之处,如有不妥,请随时联系删除。
[1]马寅.基于CCD的图像特征提取与识别[D].东北大学,2012.DOI:10.7666/d.J0120301.
[2]王妞,康辉英.基于图像检测的船舶特征分割与提取优化算法[J].舰船科学技术, 2018(4X):3.DOI:CNKI:SUN:JCKX.0.2018-08-049.
[3]尹聪.彩色图像人脸检测与特征提取认证[J].信息技术与信息化, 2009.DOI:JournalArticle/5af35bd8c095d718d80b8d86.
[4]罗文辉,王三武.基于面积和结构特征的水表图像二步分割方法[J].武汉理工大学学报:信息与管理工程版, 2006, 28(5):4.DOI:10.3963/j.issn.1007-144X.2006.05.014.