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

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;

답변 (1개)

akshatsood
akshatsood 2024년 7월 16일
편집: akshatsood 2024년 7월 16일
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

@akshatsood FIrst off thank you so much. Sadly, Imfind circles was one of the first things I tried however I had no luck at all with the function thats why I was hoping someone more expereineced would be able to provide preprocessing code so that the dots would become more clearly contrasted in the image. I really appreciate your help anyways though!
Dear @Bera,
Please confirm if you also used the "adapthisteq" function for enhancing the contrast of the image. Further, I would be happy to assist you further in achieving the desired preprocessing results.
To provide more effective assistance, it would be helpful if you could share the image you are working on, especially if it is not producing the expected results. Furthermore, if there is a baseline image or standard to which you are comparing your current image, please share that as well. This information will enable me to better understand the discrepancies and offer more precise guidance.
I can provide you with some of the raw photos I have!
Dear @Bera,
As you mentioned earlier that you have used the "imfindcircles" function but did not get the expected results. I would recommend enhancing the "Sensitivity" attribute which makes the alorightm more robust in detecting weak and partiallially obscured circles. Have a look at the following link for more information on this attribute.
Moreover, I am attaching a few examples from the doumentation, which could be helpful for you in figuring out a good approach in extracting out the circles from the provided image
  1. https://in.mathworks.com/help/images/detect-and-measure-circular-objects-in-an-image.html
  2. https://in.mathworks.com/help/images/identifying-round-objects.html
Thank you @akshatsood I really appreciate all the help you have been providing me. Sadly as I mentioned I tried even changing the settings and most times when I made the sensitivity too high I would detect noise clusters as circles and when I made it too low I would detect nothing vice versa. If you'd like I could send more raw images if you would want to test what I mean though!
Any other recommendations would be much appreciate and even this is more than I could have asked, so i really appreciate it!
Dear @Bera, Thank you for the response.
Please share some more images, I would take a look at it and revert if I have some pointers for you.
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.
@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

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Image Processing Toolbox에 대해 자세히 알아보기

제품

릴리스

R2024a

질문:

2024년 5월 22일

편집:

2024년 7월 18일

Community Treasure Hunt

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

Start Hunting!

Translated by