Detect quantum wire dots (appear as circles) and isolate them from noisy background binarized

4 views (last 30 days)
Hey All
I am working on a project involving photos from a live feed of quantum wire dots and I was wondering what might be the best approach for isolating the circles and the excited laser properly. My current code can sometimes lead to mistakes and non-circular formations. Any help would be much appreciated. I have shared my current code as well as an image comparison below!
I = "QD.jpg"
%loads image from a file into an array
Img = imread(I);
%grayscales image for easier analysis
ImgGray = im2gray(Img);
%makes a clear contrast between foreground and background
adjustedImg = imadjust(ImgGray);
%binarizing image into 0(black) and 1(white)
BwImg = imbinarize(adjustedImg, 'adaptive', 'ForegroundPolarity', 'dark', 'Sensitivity', 0.4);
%inverting it so that foreground appears as white and background as black
invertedBwImg = ~BwImg;
%morpholigically changing the image by opening and closing, in this case removing small white
%objects from black background and removing the remaining black spots from
%the white patches
se = strel("disk",15);
openedImg = imopen(invertedBwImg,se);
closedImg = imclose(openedImg,se);
% Apply a threshold to keep only pixels above the threshold value
thresholdedImg = ImgGray > 120;
% Multiply the original grayscale image by the threshold mask to keep pixel values
excitedimg = uint8(thresholdedImg) .* ImgGray;
% Label connected components
labeledImg = bwlabel(closedImg);
% Measure properties of image regions
stats = regionprops(labeledImg, 'Eccentricity');
% Define an eccentricity threshold
eccentricityThreshold = 0.76;
% Initialize a mask for the filtered image
filteredImg = ismember(labeledImg, find([stats.Eccentricity] < eccentricityThreshold));
% Convert logical image(filterImg) to uint8 image in order to comebine with
% excitedimage
uint8Img = uint8(filteredImg) * 255;
%final image with excited light and quantum wires
finalImg = uint8Img + excitedimg;
% Create a new figure for displaying images
figure;
% Display the original image
subplot(1, 2, 1);
imshow(Img);
title('Original Image');
% Display the filtered binary image
subplot(1, 2, 2);
imshow(finalImg);
title('Updated Result');
% Return the figure handle as the result
result = gcf;

Answers (1)

akshatsood
akshatsood on 16 Jul 2024
Edited: akshatsood on 16 Jul 2024
Dear @Bera,
I understand that your goal is to detect quantum wire dots and isolate them from a noisy, binarized image background. To achieve this, I recommend leveraging the "imfindcircles" function from the Image Processing Toolbox. This function is highly effective for locating circular objects within an image by utilizing the circular Hough transform.
The "imfindcircles" function can be invoked using the following syntax:
% finds the circles in image A whose radii are approximately equal to radius. The output,
% centers, is a two-column matrix containing the (x,y) coordinates of the circle centers.
centers = imfindcircles(A,radius)
% finds circles with radii in the range specified by radiusRange. The output argument,radii,
% contains the estimated radii corresponding to each circle center in centers.
[centers,radii] = imfindcircles(A,radiusRange)
Once you have the centers and the radius, you can use the function "viscircles" for drawing circle on the image.
% draws circles with specified centers and radii onto the current axes. You can use the
% imfindcircles function to find the centers and radii of circles in an image.
viscircles(centers,radii)
Further, I have the following suggestions for enhancing image contrast and improving morphological operations:
  1. Adaptive Histogram Equalization: Use the "adapthisteq" function for adaptive histogram equalization. This technique can significantly enhance the contrast of grayscale images by adjusting the intensity distribution of the pixels, making features more distinguishable.
  2. Noise Reduction: Apply the "bwareaopen" function to remove small objects from binary images.
For detailed information on these functions, please refer to their respective documentation:
  1. imfindcircles - https://www.mathworks.com/help/images/ref/imfindcircles.html?s_tid=doc_ta
  2. viscircles - https://www.mathworks.com/help/images/ref/viscircles.html?s_tid=doc_ta
  3. bwareaopen - https://www.mathworks.com/help/images/ref/bwareaopen.html?s_tid=doc_ta
  4. adapthisteq - https://www.mathworks.com/help/images/ref/adapthisteq.html?s_tid=doc_ta
I hope this helps.
  11 Comments
akshatsood
akshatsood on 18 Jul 2024
Edited: akshatsood on 18 Jul 2024
Dear @Bera, Thank you for sharing the images.
I have developed a script that utilizes the imfindcircles function in combination with a custom function to remove overlapping circles from the image. Through experimentation, I found that a "Sensitivity" value of 0.88 works well, along with a suitable range of radii for circle detection.
Please find the script below. I have made an effort to use meaningful variable names and added comments for clarity. This script can serve as a starting template for you, allowing you to add more preprocessing steps.
img = imread('image.jpeg');
% Convert the image to grayscale if it's not already
if size(img, 3) == 3
grayImg = rgb2gray(img);
else
grayImg = img;
end
% Detect circles in the grayscale image
[centers, radii, metric] = imfindcircles(grayImg, [25, 250], 'ObjectPolarity', ...
'dark', 'Sensitivity', 0.88);
% Remove overlapping circles
if ~isempty(centers)
[centers, radii, metric] = removeOverlappingCircles(centers, radii, metric);
end
% Draw the detected circles on the image
if ~isempty(centers)
circles = [centers, radii];
imgWithCircles = insertShape(img, 'Circle', circles, 'LineWidth', 3, ...
'Color', 'blue');
else
imgWithCircles = img; % No circles found, keep the original image
end
% Display the image with circles
imshow(imgWithCircles);
% Function to remove overlapping circles
function [finalCenters, finalRadii, finalMetric] = removeOverlappingCircles( ...
centers, radii, metric)
% Sort circles by their metric (strongest first)
[~, idx] = sort(metric, 'descend');
centers = centers(idx, :);
radii = radii(idx);
metric = metric(idx);
% Initialize the list of final circles
finalCenters = [];
finalRadii = [];
finalMetric = [];
while ~isempty(centers)
% Take the strongest circle and add it to the final list
finalCenters = [finalCenters; centers(1, :)];
finalRadii = [finalRadii; radii(1)];
finalMetric = [finalMetric; metric(1)];
% Remove circles that overlap with the strongest circle
distances = sqrt((centers(:, 1) - centers(1, 1)).^2 + ...
(centers(:, 2) - centers(1, 2)).^2);
overlapIdx = distances < (radii + radii(1));
centers(overlapIdx, :) = [];
radii(overlapIdx) = [];
metric(overlapIdx) = [];
end
end
Please note that, this might not be robust for all scenarious and woud require your efforts in performing pre-processing steps to bring out quantum wire dots more distinctively from the image easing their detection.
I will continue exploring additional approaches to meet your requirements. If I discover any noteworthy methods, I will share them here. Until then, I hope the provided script will be helpful for detecting wire dots in your images.
Bera
Bera on 18 Jul 2024
@akshatsood Your a legend mate thank you so much I'm in my lab currently but when I get the chance to test it I'll let you know if I am getting the results I want

Sign in to comment.

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!