이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
remove boundary contours from the image
조회 수: 15 (최근 30일)
이전 댓글 표시
Hi, I have an attached image, and I want to delete everything outside the middle circle.
From its binary data, I tried some implementations by replacing some 255 values with 0.
And I want to know if there is a specific way of removing specified contours.
Thank you for your time in advance.
Best regards
MB
답변 (1개)
Image Analyst
2020년 1월 19일
Do you know the diameter of the inner circle? If so, just use the FAQ to create a circle mask, and mask it away
mask(circleMask) = false;
Can I see the original image that you made this edge image from? Because it might be possible to get a mask using thresholding instead of edge detection. Edge detection is usually NOT the first thing you want to do to an image. For most images thresholding is the way to do, with phase contrast and DIC microscopy images being one exception where you might want to do edge detection.
댓글 수: 35
Mammadbaghir Baghirzade
2020년 1월 19일
Hi Image Analyst,
I appreciate for your time.
My aim is to calculate the surface area of the inner circle.
Using the " d = imdistline" I measured the radius of a circle, however, my goal is to get the area.
Since, somtimes the inner figure is not a full circle, using A=2*pi*r will not work all the time.
I have utilized your previously answered questions as well, but I couldn't figure it out.
Please find attached image.
I planned to get edge using canny edge, and then somehow to get the area of the place surrounded by the contour. Nevertheless, I couldn't get the contour of only middle section.
Is there anyway of measuring the area of the inner shape?
Image Analyst
2020년 1월 19일
편집: Image Analyst
2020년 1월 19일
OK that might be a candidate for edge detection since the rgay levels inside the edge are the same as outside. How about if you threshold to get the dark surround then make a mask of that,
mask = grayImage < 50; % or whatever
and get the mode of the image inside that?
modeValue = mode(grayImage(~mask));
Then set the image in the corners to that gray level to make them be the same intensity as the outer circle.
grayImage(mask) = modeValue;
% Now do Canny edge detection.
What was the code you used to get the edge image? This will eliminate, or greatly reduce the edges due to the outer circle and you can then just concentrate on the inner circle, like maybe using bwconvhull() or something.
Mammadbaghir Baghirzade
2020년 1월 19일
I attached Canny edge code. I downloaded it from Mathworks website.
I have tried your suggested steps, but it did not work.
Mammadbaghir Baghirzade
2020년 1월 19일
Yes, I have tried.
However, the thing that I did not like was, for every image I needed to specify the radius correctly to be able to see the contour around the circle. And in most cases, that contours were not alligned with my circle.
Image Analyst
2020년 1월 20일
You just need to know a range of circle radii, not the radius exactly. I would also like that if I would mask out the outer circle. Do you know anything about the range? Like can the inner circle be anywhere from 0 to 100% of the outer circle? Or is it in some range, like 5% to 75% of the outer one?
Mammadbaghir Baghirzade
2020년 1월 20일
I do not know that range. Do you know how to get the range from an image?
That circles starts from a point and increases ntil the outer circle.
I will work on each image at the end. Therefore, that range will change in every image.
Do you know how to get that range?
Image Analyst
2020년 1월 20일
How about if you just scan the image across columns and delete the first and last white pixel in each column? That would delete the outer one.
[rows, columns] = size(mask);
for col = 1 : columns
topRow = find(mask(:, col), 1, 'first');
if ~isempty(topRow)
mask(topRow, col) = false; % Erase top row.
bottomRow = find(mask(:, col), 1, 'last');
mask(bottomRow, col) = false; % Erase bottom row.
end
end
then call bwareaopen() to get rid of other, remaining small clutter blobs.
Image Analyst
2020년 1월 20일
Very strange. Are you sure you were using the binary/logical edge image from the Canny process? And are you sure it's logical, not uint8 (gray scale)?
Mammadbaghir Baghirzade
2020년 1월 20일
I guess I am missing or applying in a wrong order the steps from our previous conversation.
Could you please list your suggested steps?
Mammadbaghir Baghirzade
2020년 1월 21일
편집: Mammadbaghir Baghirzade
2020년 1월 21일
I remembered that, I have the image of the chamber without any experiment, so I can substract 2 images from each other (please see attached images).
However, I did not get satisfactory result.
Do you any suggestion on this?
Mammadbaghir Baghirzade
2020년 1월 21일
I appreciate your quick response.
I got the attached image.
Then, actually tried to apply canny edge to get the contour, but it was not good.
Image Analyst
2020년 1월 21일
No, you don't use edge detection anymore. You threshold.
mask = grayImage > someValue; % Binarize the image.
% Take 2 largest blobs
mask = bwareafilt(mask, 2); % Or use bwareaopen().
% Get the convex hull
chImage = bwconvhull(mask, 'union');
areaInPixels = nnz(mask)
Image Analyst
2020년 1월 21일
To that subtraction image:
diffImage = imabsdiff(originalImage, referenceEmptyImage);
mask = diffImage > someValue; % Binarize the image.
% Take 2 largest blobs
mask = bwareafilt(mask, 2); % Or use bwareaopen().
% Get the convex hull
chImage = bwconvhull(mask, 'union');
areaInPixels = nnz(mask)
Mammadbaghir Baghirzade
2020년 1월 21일
Also, I confuse how to decie on "someValue"?
Do you have any asuggestions on that?
Image Analyst
2020년 1월 21일
or you can just guess values of 1, 2, 3, 4, 5, etc. until you find one that looks good.
Mammadbaghir Baghirzade
2020년 1월 21일
Hi,
It seems that following line did not binarized the mask.
mask = diffImage > 26; % Binarize the image.
Do you have any suggestions?
Because I got the following error.
Error using bwpropfilt
Expected input number 1, BW, to be two-dimensional.
Error in bwpropfilt>parse_inputs (line 118)
validateattributes(bw, {'logical'}, {'nonsparse', '2d'}, mfilename, 'BW', 1);
Error in bwpropfilt (line 57)
[bw, I, attrib, p, direction, conn] = parse_inputs(varargin{:});
Error in bwareafilt (line 33)
bw2 = bwpropfilt(bw, 'area', p, direction, conn);
Error in IAcode (line 8)
mask = bwareafilt(mask, 2); % Or use bwareaopen().
>>
Image Analyst
2020년 1월 22일
It looks like you are somehow still dealing with an RGB image. You need to make sure diffImage is a 2-D gray scale image, not an RGB image. If you do that, mask will be a 2-D binary/logical image and it should work. Right after you call imread(), just have this code:
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
% grayImage = rgb2gray(rgbImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
grayImage = grayImage(:, :, 2); % Take green channel.
end
% Now it's gray scale with range of 0 to 255.
Mammadbaghir Baghirzade
2020년 1월 22일
Thank you so much, I will try it and will let you know about the progress.
I appreciate for your kind help and for your time.
Mammadbaghir Baghirzade
2020년 1월 23일
Hi,
So far, it was one of the best improvements. I really appreciate your help.
areaInPixels = nnz(mask) "Does this give me the area of the white region?"
Thank you
Image Analyst
2020년 1월 23일
That gives you the number of white pixels. That can be considered as one way to measure the area. And maybe it's fine for you to discriminate between two slightly different images.
Image Analyst
2020년 1월 23일
You could, but most people don't. Most everybody understands that when you give a distance, the units are pixels (if you're not spatially calibrating to real world units such as centimeters, like with my attached demo code), and that if you're talking about area, the units are also pixels, not pixels squared. It's just understood. People know what you're talking about from the context (length or area). I'm sure they'd also figure it out if you said pixels squared, but that would be unconventional terminology.
Mammadbaghir Baghirzade
2020년 1월 23일
Thanks. My aim is to convert that value to cm^2. Do you have any suggestions on that?
Mammadbaghir Baghirzade
2020년 1월 23일
Thank you.
I tried to understand the code, which is a little bit long.
Should I first take the white region from my image and then use that white region for your demo code?
Image Analyst
2020년 1월 23일
Basically you need to define a spatial calibration factor, like 3 cm = 450 pixels or whatever. So you'd make a factor like
spatialCalibration = 3/450; % Factor to convert pixels to cm.
so if you multiply pixels * (cm/pixel) you get cm, because the pixels cancel out.
distanceInCm = distanceInPixels * spatialCalibration;
If you have an area then you need to multiply by that squared
areaInSquareCM = areaInPixels * spatialCalibration^2;
to get the area in square cm.
Mammadbaghir Baghirzade
2020년 1월 24일
I understand thank you very much.
I used the following command to draw a line and to get the number of the pixels along the line (not the pixel values).
w=improfile(Image, xline, yline); which gave me following result.
w 36x1x3.
My questions is:
Is saying the number of the pixels along the line 36 correct?
Image Analyst
2020년 1월 24일
Yes. The default spacing, if nothing is specified otherwise, is 1 pixel. It interpolates it because chances are that the locations will not fall exactly on pixel centers (unless the line is perfectly along a row or column).
Mammadbaghir Baghirzade
2020년 1월 26일
I understand thank you very much.
To make sure that I count the pixels along the horizontal line, I run the following script.
[x,y] = ginput(2);
xline = [x(1), x(2)];
yline = [y(1), y(1)];
w=improfile(I, xline, yline);
hold on
imshow(I)
hold on
%show a line
line ([xline(1), xline(2)],[yline(1), yline(2)]);
figure(1);line([0 1],[0 1]);
Because of curiosity I run both w=improfile(I, xline, yline) and w=improfile(I, x, y).
And it gave me the same number of pixels for xline and x from w=improfile(I, xline, yline) and w=improfile(I, x, y).
If going with w=improfile(I, xline, yline) is not correct, do you have any suggestion that wil count the pixels only along horizontal line.
참고 항목
카테고리
Help Center 및 File Exchange에서 Image Processing Toolbox에 대해 자세히 알아보기
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 (한국어)