how do I draw discriminatory lines in an image to calculate the area in each of those regions?
2 次查看(过去 30 天)
显示 更早的评论
Hello, I am exploring matlab and I was wondering how do i draw circular lines that classify particular regions of that image? So that later on I can calculate the area of that region seperatley than the other regions?
I have several images and I am wondering which methods I can use to segment regions within that image from other regions in that same image.
Thank you
1 个评论
采纳的回答
Image Analyst
2023-1-10
See the FAQ:
See attached drawing demos.
19 个评论
Neo
2023-1-10
编辑:Neo
2023-1-10
thanks for this, great tools but if i just draw equally-spaced shapes how can i tell the code that i will use to calculate the area that I only want to calculate the area within a specific shape? I guess the confusion is that I THINK I have to write a code that can identify the partitions in the image and note that each partition HAS ITS OWN area measurement and prevent the code from calculating the area of the whole image together.
Image Analyst
2023-1-10
Somehow you have to segment the image into two or more regions, like foreground and background, or left third, middle third, right third, or whatever. Once you have those regions identified, you can call regionprops to get attributes for each region. How do you want to segment each region? By hand drawing, or according to some mathematical formula of circles?
Neo
2023-1-10
regionprops sounds promising. i want to segment the image into 12 equal partitions. (What is inside the partition will differ, that's why.)
i just want to segment them in equal partitions across the image. So I don't mind HOW they're partitioned as long as they are partitioned evenly in the image and also when it is time to calculate the area of each partition the line can act as indicator that the area is only calculated for that partition.
Alt. the line can be hand drawn and as long as there is some indicator that the image is partitioned that's fine too.
Image Analyst
2023-1-10
If you just want the mean gray level in 12 strips going across the image, try this:
% Demo by Image Analyst
% Find the mean gray level in 12 strips going across the image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = [];
baseFileName = 'cameraman.tif';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% 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)
rows = 256
columns = 256
numberOfColorChannels = 1
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgb2gray(grayImage);
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(1, 3, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Update 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)
rows = 256
columns = 256
numberOfColorChannels = 1
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get mean across 12 vertical bands of the image
startingColumns = round(linspace(1, columns+1, 13))
startingColumns = 1×13
1 22 44 65 86 108 129 150 172 193 214 236 257
endingColumns = startingColumns(2:end) - 1
endingColumns = 1×12
21 43 64 85 107 128 149 171 192 213 235 256
for k = 1 : length(endingColumns)
col1 = startingColumns(k);
col2 = endingColumns(k);
% Make a strip
mask = false(size(grayImage));
mask(:, col1:col2) = true;
subplot(1, 3, 2);
imshow(mask);
impixelinfo;
axis('on', 'image');
caption = sprintf('Mask #%d', k);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Crop the image so we get the image in the mask
subImage = grayImage(:, col1 : col2);
subplot(1, 3, 3);
imshow(subImage);
impixelinfo;
axis('on', 'image');
caption = sprintf('Subimage #%d', k);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Make measurements of mean graylevel.
meanGL(k) = mean(grayImage(mask));
end
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1258480/image.png)
meanGL
meanGL = 1×12
146.379836309524 124.317294034091 73.9890252976191 60.8411458333333 85.0129616477273 95.8610491071429 126.819754464286 140.714133522727 144.698474702381 147.955357142857 143.329190340909 133.895833333333
Neo
2023-1-10
I tried this algorithm it looks like it will work so I added in my image (attached) and inserted these lines to turn it to gray scale:
baseFileName = 'test1.jpg';
baseFileName = baseFileName(:, :, 1);
And got this error:
Error using images.internal.imageDisplayValidateParams>validateCData
If input is logical (binary), it must be two-dimensional.
Error in images.internal.imageDisplayValidateParams (line 30)
common_args.CData = validateCData(common_args.CData,image_type);
Error in images.internal.imageDisplayParseInputs (line 79)
common_args = images.internal.imageDisplayValidateParams(common_args);
Error in imshow (line 253)
images.internal.imageDisplayParseInputs({'Parent','Border','Reduce'},preparsed_varargin{:});
Error in untitled2 (line 70)
imshow(mask);
Image Analyst
2023-1-10
What is this:
baseFileName = 'test1.jpg';
baseFileName = baseFileName(:, :, 1);
??? baseFileName is a string, not a three dimensional array, so you can't get slice #1 from a string.
Anyway, it looks like your image is probably color, not gray scale. If you want to process color images then you need to decide what you want to do to each color channel, and extract them as gray scale images like this:
[r, g, b] = imsplit(rgbImage);
Now r, g, and b are 2-D gray scale images, not color images, and you can use my code.
Neo
2023-1-10
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 binning (line 15)
[r, g, b] = imsplit(baseFileName);
Should i convert it to something else?
Image Analyst
2023-1-11
Did I say to use it on the file name string? No. I said to use it on the image variable:
[r, g, b] = imsplit(rgbImage);
Not sure why you changed the variable from a 2-D uint8 matrix to a character array string, and didn't just do
baseFileName = 'test1.jpg';
rgbImage = imread(baseFileName);
[r, g, b] = imsplit(rgbImage);
% Let's assume you want to work on the red channel image, r. So...
mask = false(size(r));
Neo
2023-1-11
编辑:Neo
2023-1-11
I think that this answer will give the answer to my question!
I ran the algorithm but it just ouputted the gray scale version of my image with the following results:
rows =
1452
columns =
5208
numberOfColorChannels =
3
It is not really gray scale like we expected - it is color
rows =
1452
columns =
5208
numberOfColorChannels =
1
startingColumns =
Columns 1 through 12
1 435 869 1303 1737 2171 2605 3039 3473 3907 4341 4775
Column 13
5209
endingColumns =
434 868 1302 1736 2170 2604 3038 3472 3906 4340 4774 5208
It did not show the mask iteration for 1-12 or the subset image. I am racking my brain to figure out what i did wrong.
Neo
2023-1-12
Attached.
The image is successfully converted to grayscale but that's it. Both are attached below. Sorry to bother you with this.
Image Analyst
2023-1-13
So are you saying you had a typo and now that you corrected it, it works now?
Image Analyst
2023-1-13
You really need to think about the code. You're throwing in lines of code randomly and changing from grayscale to RGB. Be consistent. You originally wanted an algorithm that only makes sense for gray scale images, which could either be a gray scale image, or an individual channel of an RGB image. My original code worked with RGB images by converting them to gray scale. They you started doing strange things to it by doing weird things with filenames, etc. Your latest image, test1.jpg, is grayscale so of course it doesn't make sense to try to get the R, G, and B color channels from it like you tried. Plus the last version of code you uploaded has most of the last part of my code missing.
Neo
2023-1-13
This is the error i get using just your original code:
Error using imsplit
Too many output arguments.
Error in bin (line 16)
[r, g, b] = imsplit(rgbImage);
rgbimage attached
sorry if i changed code i am bilingual sometimes i change to make more sense to me or put in translator to follow directions easily. but i have now input just your original code and still have error
Image Analyst
2023-1-13
That's not an RGB image so all that stuff about RGB images does not apply. It's just a gray scale image so my original code should work:
% Demo by Image Analyst
% Find the mean gray level in 12 strips going across the image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = [];
baseFileName = 'testrgbimage.tif';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% 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.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgb2gray(grayImage);
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(1, 3, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Update 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)
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get mean across 12 vertical bands of the image
startingColumns = round(linspace(1, columns+1, 13))
endingColumns = startingColumns(2:end) - 1
for k = 1 : length(endingColumns)
col1 = startingColumns(k);
col2 = endingColumns(k);
% Make a strip
mask = false(size(grayImage));
mask(:, col1:col2) = true;
subplot(1, 3, 2);
imshow(mask);
impixelinfo;
axis('on', 'image');
caption = sprintf('Mask #%d', k);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Crop the image so we get the image in the mask
subImage = grayImage(:, col1 : col2);
subplot(1, 3, 3);
imshow(subImage);
impixelinfo;
axis('on', 'image');
caption = sprintf('Subimage #%d', k);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Make measurements of mean graylevel.
meanGL(k) = mean(grayImage(mask));
end
meanGL
Neo
2023-1-13
If you just want the mean gray level in 12 strips going across the image:
What does it mean to have the measure the gray level? Also how to read the output ?
startingColumns =
1 44 86 129 172 214 257 300 342 385 428 470 513
endingColumns =
43 85 128 171 213 256 299 341 384 427 469 512
Image Analyst
2023-1-13
The gray level is the brightness of the image pixels.
Those values are the starting and stopping columns of the vertical strip where we are going to get the mean intensity in.
更多回答(1 个)
Matt J
2023-1-9
编辑:Matt J
2023-1-9
I was wondering how do i draw circular lines
More generally, you can segment interactively with the Segmenter App
21 个评论
Neo
2023-1-9
Thank you. Since I want to draw circular lines (not cirlces) can you suggest a method that could give me identical ciruclar lines to segment the regions in the image?
The segmenter app is a great start but since its option is to hand drawn the lines, the lines won't be identical to each other. I am sorry to bother you about that. Thank you for your suggestion.
Regards
Neo
2023-1-9
Sorry, please see the attached image.
i want to generate these lines unfiormly in the image such that i can calculate the area within each of these regions seperatley from the others.
Sorry for that.
Neo
2023-1-9
So the method can also include how to calculate the enclosed region area for each curved line.
Matt J
2023-1-9
The segmenter app is a great start but since its option is to hand drawn the lines, the lines won't be identical to each other.
The lines in your images are curved, but they don't look circular. What is meant to determine their shape if they are not to be hand-drawn? Are they all meant to be shifted copies of one another? If so, you can draw one line with drawfreehand and then copy them.
Matt J
2023-1-10
They are separate problems. How you draw/specify the boundaries will not have anything to do with how you then calculate areas between them.
Neo
2023-1-10
Area is the length x width sorry to bother you sir but that means the shape will be connected to the area. I need the curved line of a region in the image to be defined in a way that it’s connected to the calculation of the area within the region. What do you suggest?
Matt J
2023-1-10
编辑:Matt J
2023-1-10
Connected in what way? You still haven't told us what the criteria is for choosing the curved boundaries. Are you saying you want the boundaries placed such that the partitioned image regions all have the same area? But that still isn't specific enough to uniquely define the boundaries. One way to partition them into equal-area regions (among many others) is to just draw equally-spaced vertical lines.
Neo
2023-1-10
编辑:Neo
2023-1-10
no criteria just want them to be equally partitioned throughout the image such that all the areas are identical (what is inside each area will be different).
if i just draw equally-spaced lines how can i tell the code that i will use to calculate the area that I only want to calculate the area within each line? I guess the confusion is that i THINK i have to write a code that can identify partitions in the image and note that each partition has its own area measurement and prevent the code from calculaating area of the whole image together.
Matt J
2023-1-10
and note that each partition has its own area measurement
??? but previously you said that all areas are identical: "just want them to be equally partitioned throughout the image such that all the areas are identical"
Matt J
2023-1-10
编辑:Matt J
2023-1-10
In any case, you can get label maps for each of the regions using cumsum, (see below), whereupon you can then use regionprops to analyze a particular region.
BW=zeros(256); BW(:,64:64:end)=1; %vertically partiioned black/white image.
RegionLabels=cumsum(BW,2);
immontage({imdilate(BW,[1,1,1]), RegionLabels},'Bord',15,'Back','w')
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1258295/image.png)
Neo
2023-1-10
and note that each partition has its own area measurement
By this I mean that each partition has its own contents but identical areas.
Neo
2023-1-10
Thanks for this. I ran the attached and got a small error:
Not enough input arguments.
Error in immontage (line 18)
if iscell(Images)
i did not see regionprops when i ran the code. Sorry to bother you
Matt J
2023-1-10
编辑:Matt J
2023-1-10
I ran the attached and got a small error:
The main code is what I appears in my post, not the attachment. immontage is a utitlity function for image display. You do not have to use immontage if you don't want to. You can use imshow or imagesc or whatever you normally use. It was just convenient for me to present it that way.
i did not see regionprops when i ran the code.
Neo
2023-1-14
i am not sure if this should be a seperate question but before I take the mean gray level in the strips, I would like to substract the background, correct for contrast, implement gaussian filtering and thresholding/binarization so i have added this code that i found from other matlab answers:
% Binarize the image.
mask = grayImage > lowThreshold & grayImage < highThreshold;
mask = imfill(mask, 'holes');
% Find out the areas
props = regionprops(mask, 'Area');
allAreas = sort([props.Area], 'descend')
% Take only blobs 20 pixels or larger
mask = bwareaopen(mask, 20);
% Update measurements.
props = regionprops('table', mask, grayImage, 'Area', 'MeanIntensity', 'MaxIntensity', 'MinIntensity');
allAreas = [props.Area]
meanIntensities = [props.MeanIntensity]
maxIntensities = [props.MaxIntensity]
minIntensities = [props.MinIntensity]
% Display the mask.
subplot(2, 2, 3);
imshow(mask, []);
title('Mask', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
maskedImage = grayImage; % Initialize.
maskedImage(~mask) = 0; % Or whatever gray level you want, such as mean(grayImage(~mask));
% Display the image.
subplot(2, 2, 4);
imshow(maskedImage, []);
title('Masked Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
what do you think?
Neo
2023-1-14
Neo
2023-1-15
I have asked it in another question but I cant tell that it has been performed background substraction, gaussian and contrast correction before mean grey level analysis. How can you?
Image Analyst
2023-1-15
I don't see anything being subtracted from the gray scale image in the code above. You need to read in a background image and then subtract it. Decide where you want to discuss this. I suggest your new thread just about background subtraction. (Note spelling of subtraction -- there are not two s's).
另请参阅
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 (한국어)