separating foreground from background and working on the masked image in matlab
5 次查看(过去 30 天)
显示 更早的评论
Malini Bakthavatchalam
2020-9-24
Hi,
This question is haunting me for a long time. first I was working in color so I have asked people here. now i am working on grey levels, but still this question is not resolved. I am reading an image using imread function then converting the whole image to grey levels, then I have to work only on the grey levels of the foreground, the code should not include the background, could anyone suggest a code to insert in my code please....i will attach a sample image as well ...
18 个评论
Malini Bakthavatchalam
2020-9-24
HI, I did try but it convers the background to black but still in my forground analysis the black pixels is getting involved ...
Sindar
2020-9-24
(caveat: that was pretty much the limit of my knowledge)
What analysis are you doing? You may need to use the mask to do something else to the image, vs changing background to black.
Spitballing:
- NaNs
- Pass non-masked pixels as a single column
- Check the documentation of the analysis functions to see if you can pass in a mask
Malini Bakthavatchalam
2020-9-25
I have attached my code, in short, I am converting a color image to gray scale, then take the foreground of the image, calculate the median,using the median splitting the image from the median into 2 separate image... so one image will have value less than median and other image will have pixels greater than median.
Sindar
2020-9-25
everything above "figure(1)" can be replaced by this cleaner version
% image included in Matlab so we can compare
I = imread('ngc6543a.jpg');
G = rgb2gray(I);
my_median = median(G,"all");
K = my_median*ones(size(G),"uint8");
P = my_median*ones(size(G),"uint8");
idx = ( G <= my_median );
K(idx) = G(idx);
P(~idx) = G(~idx);
if you have a mask as a size(G) set of true/false in variable BW (the first output from image Segmenter app auto-generated code), then replace the my_median line with:
my_median = median(G(mask));
With the sample image and a segmenting function below, I get this:
G
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/366100/image.png)
[BW,G_masked] = segmentImage(G);
G_masked
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/366103/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/366106/image.png)
Your plots
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/366109/image.png)
Segmenter code
function [BW,maskedImage] = segmentImage(X)
%segmentImage Segment image using auto-generated code from imageSegmenter app
% [BW,MASKEDIMAGE] = segmentImage(X) segments image X using auto-generated
% code from the imageSegmenter app. The final segmentation is returned in
% BW, and a masked image is returned in MASKEDIMAGE.
% Auto-generated by imageSegmenter app on 24-Sep-2020
%----------------------------------------------------
% Threshold image - manual threshold
BW = X > 25;
% Close mask with disk
radius = 20;
decomposition = 0;
se = strel('disk', radius, decomposition);
BW = imclose(BW, se);
% Clear borders
BW = imclearborder(BW);
% Erode mask with disk
radius = 1;
decomposition = 0;
se = strel('disk', radius, decomposition);
BW = imerode(BW, se);
% Create masked image.
maskedImage = X;
maskedImage(~BW) = 0;
end
KALYAN ACHARJYA
2020-9-25
编辑:KALYAN ACHARJYA
2020-9-25
Although you elaborate the question quite thoroughly, but sorry I didn't understand this question exactly. What does those forground and background means here?
Steps: 1. You have gray image
2 You segment the ROI, result image is also gray image (After mask applied)
3 Next--???
Sindar
2020-9-25
I don't know if they're including it in the analysis, but the background is changing in that video (just in "darks", not "lights")
Anyway, I wasn't really thinking about the histograms. That's easy to fix, just replace the lines like this:
subplot(234)
imhist(G(BW))
title('originalhist');
subplot(235)
imhist(K(BW))
title('lowerrectified hist');
ylim([0 10000])
subplot(236)
imhist(P(BW))
title('upperrectified hist');
ylim([0 10000])
If you don't want the backgrounds to be changed (even according to the median of the foreground), use these lines to compute K and P
K = use_median*ones(size(G),"uint8");
P = use_median*ones(size(G),"uint8");
idx_dark = ( G <= use_median ) | ~BW;
K(idx_dark) = G(idx_dark);
idx_light = ( G > use_median ) | ~BW;
P(idx_light) = G(idx_light);
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/366136/image.png)
Malini Bakthavatchalam
2020-9-26
so with this Do I have to keep marking my foreground all the time?, because i have 100 images.
Malini Bakthavatchalam
2020-9-26
@kalyan Acharjya: Thanks for the question, I am basically taking a color image, separating the foreground, then converting that foreground into grey levels, then finding the median for the foreground, Finally i create two more images from the median value splitting them into half. the answer is already given by Sindar. thanks to Sinder. Now my question is this image segmentar is asking to mark both foreground and background. I have 100 images to work, so making this foreground and background selection looks tough.. Could you suggest some better ways please...
Sindar
2020-9-26
First, the code:
It seems mostly like the algorithm is correct, but many lines refer to variables that aren't defined. Here's a functional version (minus the image segmenter):
clc
close all
clear all
I = imread('img29res.jpg');
G = rgb2gray(I);
[BW,G_masked] = segmentImage(G);
% change to true if you want to use the median of the whole image
if false
my_median = median(G,"all");
K = my_median*ones(size(G),"uint8");
P = my_median*ones(size(G),"uint8");
idx = ( G <= my_median );
K(idx) = G(idx);
P(~idx) = G(~idx);
else
my_median = median(G(BW));
K = my_median*ones(size(G),"uint8");
P = my_median*ones(size(G),"uint8");
idx_dark = ( G <= my_median ) | ~BW;
K(idx_dark) = G(idx_dark);
idx_light = ( G > my_median ) | ~BW;
P(idx_light) = G(idx_light);
end
figure(1)
subplot(3,3,1)
imshow(I)
title('original');
subplot(3,3,2)
imshow(G)
title('grayscale');
subplot(3,3,3)
imshow(BW)
title('foreground mask');
subplot(3,3,4)
imshow(G_masked)
title('orginal foreground');
subplot(3,3,5)
imshow(K)
title('lower rectified');
subplot(3,3,6)
imshow(P)
title('upper rectified');
subplot(3,3,7)
imhist(G(BW))
title('originalhist');
% get the limits of the orginal histogram and use the same for others
yl=ylim();
subplot(3,3,8)
imhist(K(BW))
title('lower rectified hist');
ylim(yl)
subplot(3,3,9)
imhist(P(BW))
title('upper rectified hist');
ylim(yl)
I added a row of plots to show the original color image, the mask itself, and just the foreground of the grayscale image.
Now, to the background/foreground segmentation:
The idea of the app is that you can play around with options to figure out what works for a few sample images. You generate code, paste it as "function [BW,maskedImage] = segmentImage(X)...". Then, you try it out on the whole batch and see if there are issues. So, no, you don't need to run the app for each image. If all your images have a solid light background, it should be relatively easy.
Right now, segmentation code you're using (mine?) doesn't work for your image:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/367009/image.png)
You can see that it identifies none of the image as foreground
I just downloaded your actual image, played around with the App, and came up with this code. It works for this particular image, but you'll need to check and adjust it so it works decently for all images:
function [BW,maskedImage] = segmentImage(X)
%segmentImage Segment image using auto-generated code from imageSegmenter app
% [BW,MASKEDIMAGE] = segmentImage(X) segments image X using auto-generated
% code from the imageSegmenter app. The final segmentation is returned in
% BW, and a masked image is returned in MASKEDIMAGE.
% Auto-generated by imageSegmenter app on 26-Sep-2020
%----------------------------------------------------
% Adjust data to span data range.
X = imadjust(X);
% Threshold image - adaptive threshold
BW = imbinarize(X, 'adaptive', 'Sensitivity', 0.630000, 'ForegroundPolarity', 'bright');
% Invert mask
BW = imcomplement(BW);
% Fill holes
BW = imfill(BW, 'holes');
% Close mask with disk
radius = 41;
decomposition = 0;
se = strel('disk', radius, decomposition);
BW = imclose(BW, se);
% Create masked image.
maskedImage = X;
maskedImage(~BW) = 0;
end
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/367012/image.png)
My suggestion would be to convert the script into a function that accepts an image, then you can run it on all of them quickly (there's even an Image Batch Processor App, but I have no experience with it)
Malini Bakthavatchalam
2020-9-27
Thanks, it worked for two to three images i have to try rest of the 96 images... all my images have only light background. Thanks so much for this help, this is a big help for my 6 months mental pressure...
I finally have only one clarification to ask, so the histogram and the lower and upper rectified images didnot involve background right ?
Sindar
2020-9-28
Yup, everything either ignores the background (histograms) or leaves it untouched (recitfying).
For histograms, you can see this here:
imhist(G(BW))
it is only creating a histogram from the masked data (i.e. the foreground)
For the rectification,
% median computed from masked data
my_median = median(G(BW));
% the below lines effectively replace all lighter-than-median foreground pixels with the median
% create an image with all pixels = median
K = my_median*ones(size(G),"uint8");
% find pixels darker than the median OR that are unmasked (i.e. the background)
idx_dark = ( G <= my_median ) | ~BW;
% replace these pixels
K(idx_dark) = G(idx_dark);
Malini Bakthavatchalam
2020-9-28
this one is created by my labmate a few yrs ago, i got this through some means, can i use the same background removal stratergy i used in my code.... in his code ... because i feel his code looks more sophisticated than mine ...
Sindar
2020-9-28
potentially... it mostly looks like they just wrapped it in a GUI for convenience, but I haven't worked with the Matlab GUI controls. On first scan, I think all you'd need to do is alter the Lightness_Stat and Lightness_HistModif functions
Malini Bakthavatchalam
2020-10-2
Sindar
2020-10-2
编辑:Sindar
2020-10-2
This segmenter algorithm will likely fail, but you may be able to build a new algorithm in the Image Segmenter app (or Color Thresholder app). It really depends on the diversity of your images. For example, I'd expect 6.jpg to be almost trivial to segment, whereas 10.jpg and 25.jpg are probably doable but trickier, and creating a single algorithm that works on all three could be difficult.
(everything else in the code will function the same)
回答(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 (한국어)