How do I threshold different objects in an image (and obtain length and angle measurements)?

2 ビュー (過去 30 日間)
Kano
Kano 2019 年 4 月 28 日
コメント済み: Kano 2019 年 5 月 4 日
Here's what I'm trying to do: first off, I wanna calculate the average threshold for the drill bit, and for the card.
Afterwards, I wanna segment the image to separate both objects (disregard the coin). Then I wanna obtain the length of the drill bit, the point angle, and the diameter.
Here's the thing: I've been told that it all has to be done automatically without using any manual inputs (such as imdist() or any GUI inputs whatsoever). Also, it has to work with any given image of drill bits. For this one, I used the card as a reference for real measurements.
I have no previous experience with Matlab whatsoever, so I've been looking at any relevant documentations, tutorials, and community topics that I could find, but I'm not quite getting exactly what I'm looking for.
Here's my feeblest attempt at obtaining average thresholds from random points on the edges of the drill bit and the card.
% Read image, store it in variable I, and convert it to grayscale
I = imread('1.jpg');
gray = rgb2gray(I);
% Use imtool(gray) to get 5 Regions Of Interest (ROIs) on the drill bit
% edges, denoting the initials and serial numbers 'D1-5' to assign them to
% the drill bit threshold calculations
croppedimg_D1 = imcrop(gray,[2075.03375681172 77.5023160620334 22.4739441746469 15.0290152994543]);
% Obtain the gray threshold using Otsu's graythresh method for each ROI,
% named TD1-5 for each point respectively
TD1 = graythresh(croppedimg_D1);
croppedimg_D2 = imcrop(gray,[1854.03375681172 83.5023160620333 22.4739441746469 15.0290152994543]);
TD2 = graythresh(croppedimg_D2);
croppedimg_D3 = imcrop(gray,[1335.03375681172 102.502316062033 22.4739441746469 15.0290152994543]);
TD3 = graythresh(croppedimg_D3);
croppedimg_D4 = imcrop(gray,[106.033756811718 202.502316062033 22.4739441746469 15.0290152994543]);
TD4 = graythresh(croppedimg_D4);
croppedimg_D5 = imcrop(gray,[129.033756811718 244.502316062033 22.4739441746469 15.0290152994543]);
TD5 = graythresh(croppedimg_D5);
% Obtain the average threshold for the drill bit by summing up ROI
% thresholds and dividing them by their count
avg_T_Drill = (TD1+TD2+TD3+TD4+TD5)/5;
% Use imtool(gray) to get 5 Regions Of Interest (ROIs) on the card
% edges, denoting the initials and serial numbers 'C1-5' to assign them to
% the card threshold calculations
croppedimg_C1 = imcrop(gray,[1733.22437414373 472.442302998379 18.4452136468276 12.3348797142872]);
% Obtain the gray threshold using Otsu's graythresh method for each ROI,
% named TC1-5 for each point respectively
TC1 = graythresh(croppedimg_C1);
croppedimg_C2 = imcrop(gray,[1205.22437414373 480.442302998379 18.4452136468276 12.3348797142872]);
TC2 = graythresh(croppedimg_C2);
croppedimg_C3 = imcrop(gray,[687.724374143729 876.442302998379 18.4452136468276 12.3348797142872]);
TC3 = graythresh(croppedimg_C3);
croppedimg_C4 = imcrop(gray,[707.224374143729 1696.94230299838 18.4452136468276 12.3348797142872]);
TC4 = graythresh(croppedimg_C4);
croppedimg_C5 = imcrop(gray,[1688.22437414373 1722.44230299838 18.4452136468276 12.3348797142872]);
TC5 = graythresh(croppedimg_C5);
% Obtain the average threshold for the card by summing up ROI
% thresholds and dividing them by their count
avg_T_Card = (TC1+TC2+TC3+TC4+TC5)/5;
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cropped_drill = imcrop(gray, [85.4999999999998 54.9999999999993 2646 254]);
% cropped_card = imcrop(gray, [665.5 448.5 2044 1301]);
%
% BW_Drill = im2bw(cropped_drill, avg_T_Drill);
% BW_Card = im2bw(cropped_card, avg_T_Card);
% imshowpair(BW_Drill, BW_Card,'montage');
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Threshold BW image using the average threshold value for the drill
BW_Thresh_Drill = imbinarize(gray, avg_T_Drill);
%Threshold another BW image using the average threshold value for the card
BW_Thresh_Card = imbinarize(gray, avg_T_Card);
%Note: BW_Thresh_Card is not used as the Red filtered color space best
%represents the card boundaries, but it's shown later for comparison
%Visualize color channels to choose the best representation of the card
Rmat = I(:,:,1);
Gmat = I(:,:,2);
Bmat = I(:,:,3);
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% imshow(Bmat)
% subplot(2,2,1), imshow(Rmat);
% title('Red Channel');
% subplot(2,2,2), imshow(Gmat);
% title('Green Channel');
% subplot(2,2,3), imshow(Bmat);
% title('Blue Channel');
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%Present BW_Red thresholded BW image using the average card threshold on the
%Red filtered color space
BW_Red = imbinarize(Rmat, avg_T_Card);
%Apply drill threshold on the BW_Final thresholded image to complement the
%threshold value over the drill
BW_Final = (BW_Thresh_Drill&BW_Red);
%Plot results
subplot(2,2,1), imshow(BW_Thresh_Drill);
title('Drill Thresh Value');
subplot(2,2,2), imshow(BW_Thresh_Card);
title('Card Thresh Value');
subplot(2,2,3), imshow(BW_Red);
title('Red Thresh Value');
subplot(2,2,4), imshow(BW_Final);
title('Sum Thresh Value');
I'm hoping this gets Image Analyst's attention!
  1 件のコメント
Kano
Kano 2019 年 5 月 4 日
Here's what I reached so far..Please let me know if there are any suggestions or anything wrong up to this point
% Read image, store it in variable I, and convert it to grayscale
I = imread('1.jpg');
gray = rgb2gray(I);
% Use imtool(gray) to get 5 Regions Of Interest (ROIs) on the drill bit
% edges, denoting the initials and serial numbers 'D1-5' to assign them to
% the drill bit threshold calculations
croppedimg_D1 = imcrop(gray,[2075.03375681172 77.5023160620334 22.4739441746469 15.0290152994543]);
% Obtain the gray threshold using Otsu's graythresh method for each ROI,
% named TD1-5 for each point respectively
TD1 = graythresh(croppedimg_D1);
croppedimg_D2 = imcrop(gray,[1854.03375681172 83.5023160620333 22.4739441746469 15.0290152994543]);
TD2 = graythresh(croppedimg_D2);
croppedimg_D3 = imcrop(gray,[1335.03375681172 102.502316062033 22.4739441746469 15.0290152994543]);
TD3 = graythresh(croppedimg_D3);
croppedimg_D4 = imcrop(gray,[106.033756811718 202.502316062033 22.4739441746469 15.0290152994543]);
TD4 = graythresh(croppedimg_D4);
croppedimg_D5 = imcrop(gray,[129.033756811718 244.502316062033 22.4739441746469 15.0290152994543]);
TD5 = graythresh(croppedimg_D5);
% Obtain the average threshold for the drill bit by summing up ROI
% thresholds and dividing them by their count
avg_T_Drill = (TD1+TD2+TD3+TD4+TD5)/5;
% Use imtool(gray) to get 5 Regions Of Interest (ROIs) on the card
% edges, denoting the initials and serial numbers 'C1-5' to assign them to
% the card threshold calculations
croppedimg_C1 = imcrop(gray,[1733.22437414373 472.442302998379 18.4452136468276 12.3348797142872]);
% Obtain the gray threshold using Otsu's graythresh method for each ROI,
% named TC1-5 for each point respectively
TC1 = graythresh(croppedimg_C1);
croppedimg_C2 = imcrop(gray,[1205.22437414373 480.442302998379 18.4452136468276 12.3348797142872]);
TC2 = graythresh(croppedimg_C2);
croppedimg_C3 = imcrop(gray,[687.724374143729 876.442302998379 18.4452136468276 12.3348797142872]);
TC3 = graythresh(croppedimg_C3);
croppedimg_C4 = imcrop(gray,[707.224374143729 1696.94230299838 18.4452136468276 12.3348797142872]);
TC4 = graythresh(croppedimg_C4);
croppedimg_C5 = imcrop(gray,[1688.22437414373 1722.44230299838 18.4452136468276 12.3348797142872]);
TC5 = graythresh(croppedimg_C5);
% Obtain the average threshold for the card by summing up ROI
% thresholds and dividing them by their count
avg_T_Card = (TC1+TC2+TC3+TC4+TC5)/5;
% read in tiff image and convert it to double format (I'm originally working with a TIF image)
my_image = im2double(I);
my_image = my_image(:,:,1);
% allocate space for thresholded image
image_thresholded = zeros(size(my_image));
% loop over all rows and columns
for ii = 1:size(my_image,1)
for jj = 1:size(my_image,2)
% get pixel value
pixel = my_image(ii,jj);
% check pixel value and assign new value
if pixel < avg_T_Drill
new_pixel = 0;
elseif pixel > avg_T_Card
new_pixel = 256;
else
new_pixel = pixel;
end
% save new pixel value in thresholded image
image_thresholded(ii,jj) = new_pixel;
end
end
BinaryImg = im2double(image_thresholded);
% Create empty mask.
BW = false(size(BinaryImg,1),size(BinaryImg,2));
% Flood fill
row = 231;
column = 1206;
tolerance = 5.000000e-02;
addedRegion = grayconnected(BinaryImg, row, column, tolerance);
BW = BW | addedRegion;
% Flood fill
row = 888;
column = 1596;
tolerance = 5.000000e-02;
addedRegion = grayconnected(BinaryImg, row, column, tolerance);
BW = BW | addedRegion;
% Fill holes
BW = imfill(BW, 'holes');
% Erode mask with disk
radius = 2;
decomposition = 0;
se = strel('disk', radius, decomposition);
BW = imerode(BW, se);
% Dilate mask with disk
radius = 3;
decomposition = 0;
se = strel('disk', radius, decomposition);
BW = imdilate(BW, se);
% Create masked image.
maskedImage = BinaryImg;
maskedImage(~BW) = 0;
% Obtain a sample column using imtool(maskedImage)
SampleCol = maskedImage(1:end, 2585);
% Find indices with white pixels
nonZeros = find(SampleCol == 256);
% Find unwanted noise indices between the drill edges
noiseIndex = find(76 < nonZeros & nonZeros < 200);
% Remove noise indices from the nonZeros vector to show only first and last white pixels of the drill and card
nonZeros(noiseIndex) = [];
% Calculate the drill diameter in pixels by subtracting the index values corresponding to the drill edges
Drill_Diameter_px = nonZeros(2) - nonZeros(1);
% Calculate the card height in pixels by subtracting the index values corresponding to the card edges
Card_Height_px = nonZeros(4) - nonZeros(3);
% Real card height is hardcoded here
Card_Real_Height = 53.98;
% Calculate Spatial Calibration factor by dividing real height in mm by height in pixels
SCF = Card_Real_Height/Card_Height_px;
% Solve for real drill diameter using the previously calculated SCF and the obtained drill diameter in pixels
Drill_Real_Diameter = SCF * Drill_Diameter_px;
% Plot results
figure, imshow(I)
hold on
plot([2585,2585],[nonZeros(3),nonZeros(4)],'--k','LineWidth',1)
caption = sprintf('Card Height = %.2f mm', Card_Real_Height);
text(2050, 600, caption, 'FontSize', 11);
plot([2585,2585],[nonZeros(1),nonZeros(2)],'-k','LineWidth',1)
caption = sprintf('Drill Diameter = %.1f mm', Drill_Real_Diameter);
text(2050, 200, caption, 'FontSize', 11,'Color','black');

サインインしてコメントする。

回答 (0 件)

カテゴリ

Help Center および File ExchangeFeature Detection and Extraction についてさらに検索

製品


リリース

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by