fill data and Make an image White

Hello
I'm new in image Processing . I have a binary image. I want to fill the missing data and after filling the missing data I want to make the lower part white as shown in figure. Can anyone here help me? My images are attached.

 Accepted Answer

This maybe a bad answer but it works: I tried to find the left and right cliffs in the image and connected them to obtain the required output.
img = rgb2gray(imread('hill1.jpg'));
img = img>50;
% figure, imshow(img,[])
filterImg = bwareaopen(img,25);
% figure, imshow(filterImg,[])
columnsWithAllZeros = all(img == 0);
% get left and right indexes
left_row = find(columnsWithAllZeros,1,'first')-1;
left_column = find(img(:,left-1),1,'first');
left_index = [left_row, left_column];
right_row = find(columnsWithAllZeros,1,'last')+1;
right_column = find(img(:,right+1),1,'first');
right_index = [right_row, right_column];
% draw a line into existing image to fill gap
hLine = imline(gca, [left_index; right_index]);
singleLineBinaryImage = hLine.createMask();
filterImg(singleLineBinaryImage) = 1;
% fill bottom
output_img = zeros(size(img));
for col = 1: size(img,2)
first_nnz_row = find(filterImg(:,col),1,'first');
output_img(first_nnz_row:end,col) = 1;
end
figure,
subplot(131), imshow(img);
subplot(132), imshow(filterImg);
subplot(133), imshow(output_img);
If you are ok with some distortion in shape, dilation works too.
dilate_img = imdilate(filterImg, strel('disk',15));
figure, imshow(dilate_img)
% fill bottom
output_img = zeros(size(img));
for col = 1: size(img,2)
first_nnz_row = find(dilate_img(:,col),1,'first');
output_img(first_nnz_row:end,col) = 1;
end
figure, imshow(output_img)
Hope this helps

14 Comments

Undefined function or variable 'left'. facing this error
I am sorry, Didn't check the feed recently. If you didn't figure it yet.
replace
"left" with "left_row" and "right" with "right_row"
I have to draw the line .. but I want to fill this gap automatically
What do you mean by automatically? The code does fill the gap automatically right? Explain clearly
Sir can you guide me how I fuse/ combine two images . one image is 2d having dimensions 512x271 and other image is 3d having dimensions 512x271x512. I want to combine them to make one image
Respected Sir
I have an image and I want to auto fill the gap from it as you have provide me a solution before . how I can fill it can you please help me in this issue . I am very thankful to you Below is the image which I want to fill gap . please help me
and I want like this
This question is not the same as your initial question.
(Previously images have a gap between two peaks; here the image reached the end).
In this case you can:
  1. draw a straight line from last column or
  2. draw a inclined line as you showed above (but at what degree?)
img = rgb2gray(imread('hill2.jpg'));
img = img>50;
% figure, imshow(img,[])
filterImg = bwareaopen(img,25);
figure, imshow(filterImg,[])
columnsWithAllZeros = all(filterImg == 0);
% get left and right indexes
left_row = find(columnsWithAllZeros,1,'first')-1;
left_column = find(img(:,left_row-1),1,'first');
left_index = [left_row, left_column];
[ ~, nrows] = size(filterImg);
% % for a straight line
% right_index1 = [nrows, left_column];
% % for an inclined line
% compute right_index with given slope of line
slope = 0.2;
right_column = round(left_column - slope *(left_row - nrows));
right_index1 = [nrows, right_column];
% draw a line into existing image to fill gap
hLine = imline(gca, [left_index; right_index1]);
singleLineBinaryImage = hLine.createMask();
filterImg(singleLineBinaryImage) = 1;
% fill bottom
output_img = zeros(size(img));
for col = 1: size(img,2)
first_nnz_row = find(filterImg(:,col),1,'first');
output_img(first_nnz_row:end,col) = 1;
end
figure,
subplot(131), imshow(img);
subplot(132), imshow(filterImg);
subplot(133), imshow(output_img);
Thanks You so much Sir .
can you guide me how i can remove object from my image .. i have multiple images and i want to remove some parts from it and fill the gap .
As i have uploaded the image . in this image i have to remove these two parts which are highlited . the ring is always in center of the image and it can be removed easyly but the second part is always changing its position from frame to frame . can you guide me how i can remove this . and fill the gap like this
Alina tom
Alina tom on 1 Jun 2018
Edited: Alina tom on 1 Jun 2018
Dear Sir
Can you Guide me how I can use your code if I have to fill multiple gaps in an image like in this image . there are multiple parts that are needs to be filled . can you help me .
For the above one, @ multiple gaps, you can adapt the code I have written take some time to modify/ use code to meet the requirements.
Second, for object detection and removal it is entirely a different question. Please post it as a new question so many others can see and give you some suggestions.
Sir I have tried a lot but not able to get the desire results . could you please help me to do this .
Actually I have multiple images , in some images there is no gap and some has one or many gaps , i don't know how to modify your code to get desire result
I tried to quickly find all the missing gaps in between two peaks and all at once.
If you also need to account for a gap at end of start to draw a line with a certain slope add the above code I provided to make this suite your requirement.
img = rgb2gray(imread('trial.jpg'));
img = img>50;
% figure, imshow(img,[])
filterImg = bwareaopen(img,25);
figure, imshow(filterImg,[])
columnsWithAllZeros = all(filterImg == 0);
% compute number of gaps
diffs = diff(columnsWithAllZeros);
numChangesTo1 = sum(diffs == 1);
% compute all the left and right row indices
allRows = find(diffs);
leftRows = allRows(1:2:end);
rightRows = allRows(2:2:end)+1;
% compute left and right column indices and draw line into image
for nGaps = 1:numChangesTo1
left_row = leftRows(nGaps); right_row = rightRows(nGaps);
left_column = find(img(:,left_row),1,'first');
left_index = [left_row, left_column];
right_column = find(img(:,right_row+1),1,'first')+1;
right_index = [right_row, right_column];
% draw a line into existing image to fill gap
hLine = imline(gca, [left_index; right_index]);
singleLineBinaryImage = hLine.createMask();
filterImg(singleLineBinaryImage) = 1;
end
% fill bottom
output_img = zeros(size(img));
for col = 1: size(img,2)
first_nnz_row = find(filterImg(:,col),1,'first');
output_img(first_nnz_row:end,col) = 1;
end
figure,
subplot(131), imshow(img);
subplot(132), imshow(filterImg);
subplot(133), imshow(output_img);
One last suggestion, I think with all the codes I provided, you can combine all this and make it suite for multiple purposes to satisfy all your conditions.
Thank You so much Sir for your time and help

Sign in to comment.

More Answers (1)

I would use a conceptually simpler approach. I'd simply find the top rows of the data that is there. Then use interp1() to estimate all the top lines, including a straight line across the "missing" portions (see red line in the figure on the left below). Then scan across filling the image from those top lines down to the bottom of the image. I think it's a lot simpler and more intuitive than Gopichandh's approach. See code below. Note that the first half of the code is just to get a binary image because you did not supply the actual binary image. The main code starts after the %====== line.
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 = 20;
%===============================================================================
% Read in gray scale demo image.
folder = pwd; % Determine where demo folder is (works with all versions).
baseFileName = '1.jpg';
% Get the full filename, with path prepended.
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
rgbImage = imread(fullFileName);
% Display the image.
subplot(1, 2, 1);
imshow(rgbImage, []);
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis on;
hp = impixelinfo();
% 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(rgbImage);
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 = rgbImage(:, :, 1); % Take blue channel.
else
grayImage = rgbImage; % It's already gray scale.
end
% Now it's gray scale with range of 0 to 255.
% Threshold it to make it binary
binaryImage = grayImage > 128;
% Display the image.
subplot(1, 2, 1);
imshow(binaryImage, []);
title('Original Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis on;
impixelinfo;
%------------------------------------------------------------------------------
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
% 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;
%=============================================================================
% Now we have our binary image and we can begin the algorithm!
%------------------------------------------------------------------------------
% First, find the top line in each column
topRows = -999 * ones(1, columns); % Initialize
for col = 1 : columns
topPixel = find(binaryImage(:, col), 1, 'first');
if ~isempty(topPixel)
topRows(col) = topPixel;
end
end
% Now interpolate missing values.
missingColumns = topRows < 0;
% Remove missing data.
x = 1 : columns;
x(missingColumns) = [];
topRows(missingColumns) = [];
% Interpolate the missing ones
xInterp = 1:columns;
topRows = round(interp1(x, topRows, xInterp)); % Round to the nearest line (row).
hold on;
plot(xInterp, topRows, 'r-', 'LineWidth', 2);
% Now we know the top line, even for those that were "missing."
% Fill in the image from the top row downwards.
for col = 1 : columns
binaryImage(topRows(col):end, col) = true;
end
% Display the final image.
subplot(1, 2, 2);
imshow(binaryImage, []);
axis on;
impixelinfo;
title('Final Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');

11 Comments

Thank you So Much Sir #ImageAnalyst for your and time .
what if I want to draw the red line at bottom edge of binary image .
I have changed the toppixel from 'first' to last and get this image
Now i want to fill the upper portion of image with white pixels instead of lower one . how i can change it .
Change this
binaryImage(topRows(col):end, col) = true;
to this:
binaryImage(1:topRows(col), col) = true;
to change all pixels from line 1 to the topRows line to white.
I find this a simpler approach than the other answer. Using interp1() is easier than finding right and left pixels and using imline() and then ORing in a binary image. If you like this approach, maybe you could vote for it.
Yes this is quite easy approach than using imline() . Thanks you so much Sir . I am just beginner in image processing . can you suggest me so good tutorials about image processing .
Thanks Sir ,
I'm Facing problem when the last part of the image is missing . like this on
this is the error "Nonfinite endpoints or increment for colon operator in index."
can you guide me how to resolve this issue
or the Start point is missing, how to manage that part . could you please guide me
Your images seemed to have white lines 2 pixels thick along the top, right, and bottom edges. So I cropped those off. I also put in a fix where there was no top row at the beginning or end to interpolate to. Fix is in the attached code.
Sir I want to interpolate the missing gap
, the interpolated values should be like this
Interpolate it to what? There's nothing there to interpolate to. Do you just want to extrapolate the first value to the left for some reason? Why? You perhaps should not even do doing anything with data on the left side of the image because there's nothing there. Why do you want to do that???
Interpolate the empty space based on the information on left side . actually this empty space is the missing data , I want to fill this data with temporary data or estimated data based on the information of left side values to make a complete image .
I have a series on images in which the gap is moving , in some images it is in the start or end , and in some images it is in the middle .
I have attached some images , from 86 to 96 image gap is at the end and in rest of images the gap is at the start of the image . hope you can understand my exact problem
I have attached all the images , these are the exact images , I have cut the image from half to upper and lower part ( by finding the middle row) to easily interpolate the missing data , after interpolation I combine the image again using cat() function .
I dont know it is good apprach or not , please guide me how i can interpolate missing data more efficiently

Sign in to comment.

Categories

Find more on Images in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!