How do I remove a white background and only keep certain objects in a binary image on MATLAB?

8 Ansichten (letzte 30 Tage)
I would like the remove the white pixels in the background, but somehow keep the white lines. How would I go about doing that.
Sorry I didn't mean to remove the question. I was trying to comment on my phone, but I must have unknowingly modified the question.
  7 Kommentare
John BG
John BG am 2 Aug. 2017
IA thanks for pointing out that the original image had white contents on the top right corner.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Image Analyst
Image Analyst am 22 Jun. 2017
Justin - are you still there? Perhaps you're still struggling over this so I made a complete and fancy demo for you. Here it is:
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 = 25;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'concrete_inverted.png';
% Get the full filename, with path prepended.
folder = []; % Determine where demo folder is (works with all versions).
fullFileName = fullfile(folder, baseFileName);
%===============================================================================
% Read in a demo image.
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.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% 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
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
axis image;
caption = sprintf('Original Gray Scale Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo();
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% Binarize the image by thresholding.
mask = grayImage > 128;
% For some reason, the top two lines of his image are all white. Blacken those 2 lines:
mask(1:2, :) = false;
% Display the mask image.
subplot(2, 2, 2);
imshow(mask);
axis on;
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
title('Binary Image Mask', 'fontSize', fontSize);
drawnow;
% Get rid of small blobs.
mask = bwareaopen(mask, 500);
% Label the image.
labeledImage = bwlabel(mask);
% Find the areas and perimeters
props = regionprops(labeledImage, 'Area', 'Perimeter');
allAreas = [props.Area];
sortedAreas = sort(allAreas, 'descend')
allPerimeters = [props.Perimeter];
% Compute circularities
circularities = allPerimeters .^ 2 ./ (4 * pi * allAreas)
sortedC = sort(circularities, 'descend')
% Keep conly blobs that are nowhere close to circular or compact.
minAllowableCircularity = 10;
keeperIndexes = find(circularities >= minAllowableCircularity);
mask = ismember(labeledImage, keeperIndexes);
% Display the mask image.
subplot(2, 2, 3);
imshow(mask);
axis on;
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
title('Intermediate Cleaned Mask', 'FontSize', fontSize);
drawnow;
% Get rid of black islands (holes) in struts without filling large black areas.
subplot(2, 2, 4);
mask = ~bwareaopen(~mask, 1000);
imshow(mask);
axis on;
axis image; % Make sure image is not artificially stretched because of screen's aspect ratio.
title('Final Cleaned Mask', 'FontSize', fontSize);
drawnow;
I think the results look pretty good, like what I think you're expecting. Don't you? If not, let me know what I could do to improve it. Basically the same original crack lines are in the image (no change in exterior shape), except that the small black islands in them are filled in, all all the little isolated white island are removed. Is that what you want? There are a few parameters/variables in there, with obvious names, that you can adjust if you want to. Please get back to me.
  71 Kommentare
Justin Johnson
Justin Johnson am 16 Sep. 2017
Ok after follow your demo and modifying my code, I believe I figured it out, I just can't seem to understand why I keep getting this error message after I changed the image to binary:
Error using bwlabel
Expected input number 1, BW, to be two-dimensional.
Error in bwlabel (line 65)
validateattributes(BW, {'logical' 'numeric'}, {'real', '2d', 'nonsparse'}, ...
Error in IInvIm (line 28)
labeledImage = bwlabel(mask);

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Image Analyst
Image Analyst am 19 Jun. 2017
Threshold it to find a binary image
binaryImage = grayImage > 128;
Then take blobs only, say, 50 pixels or larger, then fill holes.
binaryImage = bwareaopen(binaryImage, 50);
binaryImage = imfill(binaryImage, 'holes');
If you then want to deal with the binary image, fine. If you want to use it to mask (blacken) the black and salty regions from your gray scale image, do this:
grayImage(~binaryImage) = 0;

John BG
John BG am 21 Jun. 2017
Bearbeitet: John BG am 23 Jun. 2017
Hi Justin Johnson
1.
to threshold the image, in order to get a binary use command imbinarize on only one RGB layer, for instance red:
clear all;close all;clc
A=imread('petri_123.jpg');
%figure(1);imshow(A);
B=imbinarize(A(:,:,1))
.
2.
while areaopen produces a good result </matlabcentral/answers/uploaded_files/81310/101.jpg>
B2=areaopen(B,50);figure(2);imshow(B2)
the suggested
B3=imfill(B,'holes');figure(3);imshow(B3)
.
fills up large areas that should remain black.
3.
another way is using imoverlay
Alab = rgb2lab(A);
[L,N] = superpixels(Alab,20000,'isInputLab',true);
BW = boundarymask(L);
figure(4);imshow(imoverlay(A,BW,'black'))
figure(5);imshow(imoverlay(A,BW,'red'))
% figure(10);imshow(imoverlay(A,BW,'white')) % doesn't work
pixelIdxList = label2idx(L);
meanColor = zeros(N,3);
[m,n] = size(L);
for i = 1:N
meanColor(i,1) = mean(Alab(pixelIdxList{i}));
meanColor(i,2) = mean(Alab(pixelIdxList{i}+m*n));
meanColor(i,3) = mean(Alab(pixelIdxList{i}+2*m*n));
end
numColors = 3;
[idx,cmap] = kmeans(meanColor,numColors,'replicates',2);
cmap = lab2rgb(cmap);
Lout = zeros(size(A,1),size(A,2));
for i = 1:N
Lout(pixelIdxList{i}) = idx(i);
end
B=label2rgb(Lout);
figure(6);imshow(B)
.
4.
Since the boundaries are cyan, extracting cyan
B1=B(:,:,1);B2=B(:,:,2);B3=B(:,:,3);
Lb2=find(B2);
Lb3=find(B3);
L23=intersect(Lb2,Lb3);
[Lx,Ly]=ind2sub(size(B2),L23);
D=zeros(size(B2));
for k=1:1:numel(Lx)
D(Lx(k),Ly(k))=255;
end
figure(7);imshow(D)
B13=B(:,:,1)-B(:,:,3);B23=B(:,:,2)-B(:,:,3);
figure(8);imshow(B13)
figure(9);imshow(B23) % still some noise left
.
5.
the boundaries of interest have the highest pixel values, all RGB closest to 255, so setting the threshold at for instance 252
A1=A(:,:,1);A2=A(:,:,2);A3=A(:,:,3);
B=zeros(size(A1));
ct=0;
thr=252; % threshold
for k=1:1:numel(A1)
if A1(k)>thr && A2(k)>thr && A3(k)>thr
ct=[ct k];
end
end
ct(1)=[];
[nx,ny]=ind2sub(size(B),ct);
for k=1:1:numel(nx)
B(nx(k),ny(k))=255;
end
figure(5);imshow(B)
.
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance
John BG
  3 Kommentare
John BG
John BG am 25 Jun. 2017
Image Analyst, your answer is far more accurate.
The question originator should give you the Accepted answer.
However I'd like to mention that when presenting this kind of image processing, larger images show more detail than the 4 subplots you have used.
subplot saves uploads, but showing each image in a separate figures helps spot details and choose.
Regards
John BG
Image Analyst
Image Analyst am 26 Jun. 2017
John, yes that is true, but then I'd have to post 4 images instead of one. I'm just used to writing code to show images in a 2 by 2 array. But sometimes small details get subsampled away.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Deep Learning Toolbox finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by