이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Camera-to-coin distance finder and comparing their values
조회 수: 3 (최근 30일)
이전 댓글 표시
Hey,
I'm just wondering that is there any chance to do that analysis which to my problem it is Image Segmentation Tutorial analysis of finding its circular are I mean diameter of any circle of the same object in different pictures?, like same coin but its getting away from the camera and in order to detect that distance I just want it to detect the radius change and make a scale for it. Is there any chance that I can do this with a similar code like yours?, Please look at my two examples; I want to calculate their area or radius and compare them with each other so that I can detect the change and find the distance irl with a scale. It would mean a lot if you just answer me back.
Best Regards,
Batuhan
채택된 답변
Image Analyst
2022년 12월 10일
Just measure the width of a known thing, like the square or circle, in each image. You can then make up a look up table of working distance (scene-to-lens distance) vs. size in pixels. From that you can fit a function to get you the mm per pixel for any distance. Then when you plug in the known distance, you can measure the size in pixels and report the size in mm.
What was the working distance for each of the two images?
댓글 수: 22
Batuhan Istanbullu
2022년 12월 10일
Plus when I do the measurement I mean finding the area of that circle, I want to find its location like this too. Is that doable?
Image Analyst
2022년 12월 10일
Wow, that's pretty close. But yes, it's do able. Since your image is red you can probably find it well like this
[r, g, b] = imsplit(rgbImage);
% Threshold blue channel, or use the Color Thresholder app if your fingers are going to be in there.
mask = b < 200;
% If you know there is only one blob, take the largest one.
mask = bwareafilt(mask, 1);
% Get area
props = regionprops(mask, 'Area');
area = props.Area
Do that for every image. So if there are 20 images, you'll have 20 areas and 20 distances in mm -- that's two 20-element vectors, or one 20 row 2-D matrix.
Batuhan Istanbullu
2022년 12월 11일
I'm trying to implement your code but I can't, I changed the name rgbImage with my picture's name like 'IMG_4461.jpg' but it gives me this error:
Error using imsplit
Expected input number 1, I, to be one of these types:
double, single, uint8, uint16, uint32, uint64, int8, int16, int32, int64, logical
Error in imsplit (line 54)
validateattributes(I,{'numeric','logical'},{'3d','nonsparse','real','nonempty'},'imsplit','I',1);
Error in batu (line 2)
[r, g, b] = imsplit('IMG_4461.jpg');
Batuhan Istanbullu
2022년 12월 11일
Okay I solved the error and found this as area =
7845080
and here is my code
rgb = imread('IMG_4461.jpg');
imshow(rgb);
% imtool (rgb) ;
d = drawline;
pos = d.Position;
diffPos = diff(pos);
diameter = hypot(diffPos(1),diffPos(2));
gray_image = rgb2gray(rgb);
imshow(gray_image)
[r, g, b] = imsplit(rgb);
% Threshold blue channel, or use the Color Thresholder app if your fingers are going to be in there.
mask = b < 200;
% If you know there is only one blob, take the largest one.
mask = bwareafilt(mask, 1);
% Get area
props = regionprops(mask, 'Area');
area = props.Area
and here is the image , Idk where I'm doing wrong but I'm trying to take measure of the largest red one.
Image Analyst
2022년 12월 11일
The problem is you're not really thinking about what the algorithm needs to do and you're just randomly tossing in useless operations, like drawing a line and converting to gray scale. Also, you're not displaying the intermediate images so you don't really know what you did last and what you need to do next.
Here, try this:
rgb = imread('IMG_4461.jpg');
% Display image.
subplot(2, 2, 1);
imshow(rgb);
impixelinfo;
title('Original RGB Image')
[r, g, b] = imsplit(rgb);
% Display image.
subplot(2, 2, 2);
imshow(b);
impixelinfo;
title('Blue Channel')
% Threshold blue channel, or use the Color Thresholder app if your fingers are going to be in there.
mask = b < 140;
% Display image.
subplot(2, 2, 3);
imshow(mask);
impixelinfo;
title('Initial Mask Image')
% Get rid of dark surround.
mask = imclearborder(mask);
% If you know there is only one blob, take the largest one.
mask = bwareafilt(mask, 1);
% Display image.
subplot(2, 2, 4);
imshow(mask);
impixelinfo;
title('Final Mask Image')
% Get area
props = regionprops(mask, 'Area', 'EquivDiameter');
area = props.Area
diameter = props.EquivDiameter
area =
235361
diameter =
547.422078919377
If you want you could also ask for Centroid and then use viscircles to put the circle at the detected location in the overlay above the image.
Now I don't know what this distance (paper-to-lens distance) this was (Looks like more than 50 mm) but then you'd have to do this for several distances to be able to create a formula that gave the lateral spatial resolution factor (in mm per pixel).
Batuhan Istanbullu
2022년 12월 11일
Well, sir you have no idea what you have just did. Thank you so much! Also do you mind If I ask something else too?, if you don't mind; the below code gives me the exact positions of the red images that I wanted to take into account, Please look at the images that I've just uploaded. I did found the exact positions of the things but I wanted to find their areas. Can I get them from workspace?
I = imread('IMG_4461.jpg');
J = imrotate(I,180);
imshow(J);
% imtool (rgb) ;
d = drawline;
pos = d.Position;
diffPos = diff(pos);
diameter = hypot(diffPos(1),diffPos(2));
gray_image = rgb2gray(J);
imshow(gray_image)
imshow(J);
% Now to track red objects in real time
% we have to subtract the red component
% from the grayscale image to extract the red components in the image.
diff_im = imsubtract(J(:,:,1), rgb2gray(J));
%Use a median filter to filter out noise
diff_im = medfilt2(diff_im, [3 3]);
% Convert the resulting grayscale image into a binary image.
diff_im = im2bw(diff_im,0.18);
% Remove all those pixels less than 11000px
diff_im = bwareaopen(diff_im,11000);
% Label all the connected components in the image.
bw = bwlabel(diff_im, 8);
% Here we do the image blob analysis.
% We get a set of properties for each labeled region.
stats = regionprops(bw, 'BoundingBox', 'Centroid');
% Display the image
imshow(J)
hold on
%This is a loop to bound the red objects in a rectangular box.
for object = 1:length(stats)
bb = stats(object).BoundingBox;
bc = stats(object).Centroid;
rectangle('Position',bb,'EdgeColor','r','LineWidth',2)
plot(bc(1),bc(2), '-m+')
a=text(bc(1)+15,bc(2), strcat('X: ', num2str(round(bc(1))), ' Y: ', num2str(round(bc(2)))));
set(a, 'FontName', 'Arial', 'FontWeight', 'bold', 'FontSize', 12, 'Color', 'yellow');
end
hold off
Batuhan Istanbullu
2022년 12월 11일
and in your code, which area or diameter is taking into account the final mask one?, if so what is their units? mm or pixels?
Image Analyst
2022년 12월 11일
Seems like you ignored everything I did and threw in useless stuff again. OK, whatever. That's not how I'd do it but you can do whatever you want.
I don't understand the grammar of "which area or diameter is taking into account the final mask one". What I am doing is taking the largest blob only and getting the area of that and the "Equivalent Circular Diameter", in other words the diameter of a circle that has the same area as the blob. It's appropriate for roughly circular things, not for squares and rectangles though. The area and diameter have units of pixels because we have not specified the field of view or real world size of the blobs. That is what you were going to do. You were going to put the camera at one distance, measure the diameter, then move the camera to a different distance and measure the diameter again, then at a different distance, and a different one, until you have maybe 5 or 10 lens-to-scene distances. So then you'd have a "pixelsPerMm" spatial calibration factor for every distance. Then you can fit those to a polynomial and be able to get the pixelsPerMm for any distance.
Batuhan Istanbullu
2022년 12월 11일
no no I didn't ignore anything, I'm just continuing with your way sir. I didn't see your solution thats why. Now I get it. Thank you for all your help !
Batuhan Istanbullu
2022년 12월 11일
'which area or diameter is taking into account the final mask one' means that, look at the image please; How can I find that area of the blacked one? Cause my object doesnt need to be circular.
Image Analyst
2022년 12월 11일
Did my way have this:
d = drawline;
pos = d.Position;
diffPos = diff(pos);
diameter = hypot(diffPos(1),diffPos(2));
gray_image = rgb2gray(J);
No. I specifically took that out.
Your last image looks absolutely nothing like the shapes drawn on paper. That image would take an entirely new algorithm.
Batuhan Istanbullu
2022년 12월 11일
Oh I see, that last image is what I'm trying to do. I'm trying to move my finger by 5 cm at every time and calculate that red the area of that red square every time and compare it.
Batuhan Istanbullu
2022년 12월 11일
That's why first I wanted to filter out the red shapes in earlier image to see that whether I can find their area while knowing their positioning in that image
Batuhan Istanbullu
2022년 12월 11일
Can't I just calculate the boundingbox area? or areas of what I bound
Image Analyst
2022년 12월 11일
If you want you can.
props = regionprops(mask, 'BoundingBox', 'Area');
allAreas = [props.Area]
bb = vertcat(props.BoundingBox);
widths = bb(:, 3);
heights = bb(:, 4);
bbAreas = heights .* widths
Image Analyst
2022년 12월 11일
편집: Image Analyst
2022년 12월 11일
Yes, so? It also works if there is only one blob in your mask.
OK let me be super explicit. Give me 5 photos:
- One taken at 50 mm camera to lens distance.
- One taken at 100 mm camera to lens distance.
- One taken at 150 mm camera to lens distance.
- One taken at 200 mm camera to lens distance.
- One taken at 250 mm camera to lens distance.
Attach them with the paperclip icon.
Batuhan Istanbullu
2023년 2월 5일
Dear Image Analyst,
I have been using the same code that you have shared with me but for whatever reason I can't find the largest blob in the picture. Can you help me where I'm doing wrong?
rgb = imread('A3.jpeg');
J = imrotate(rgb,180);
subplot(2, 2, 1);
imshow(J);
impixelinfo;
title('Original RGB Image')
[r, g, b] = imsplit(J);
subplot(2, 2, 2);
imshow(r);
impixelinfo;
title('Blue Channel')
mask =r <110 ;
subplot(2, 2, 3);
imshow(mask);
impixelinfo;
title('Initial Mask Image')
mask = imclearborder(mask);
mask = bwareafilt(mask, 1);
subplot(2, 2, 4);
imshow(mask);
impixelinfo;
title('Final Mask Image')
% Get area
props = regionprops(mask, 'Area', 'EquivDiameter', 'BoundingBox', 'Centroid');
area = props.Area;
diameter = props.EquivDiameter;
hold on
for object = 1:length(props)
bb = props(object).BoundingBox;
bc = props(object).Centroid;
rectangle('Position',bb,'EdgeColor','r','LineWidth',2)
plot(bc(1),bc(2), '-m+')
a=text(bc(1)+15,bc(2), strcat('X: ', num2str(round(bc(1))), ' Y: ', num2str(round(bc(2)))));
set(a, 'FontName', 'Arial', 'FontWeight', 'bold', 'FontSize', 12, 'Color', 'yellow');
end
Image Analyst
2023년 2월 5일
This should do it:
mask = bwareafilt(mask, 1);
subplot(2, 2, 4);
imshow(mask);
If all you see is black, then there is nothing in the original mask image -- no blobs at all.
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)