How to push a first whites (which is not equal to 0) elements from the mask image into the vector array to make line over stored points.
2 views (last 30 days)
Show older comments
kanika bhalla
on 17 Jun 2021
Commented: kanika bhalla
on 18 Jun 2021
I have scanned my image horizontally and vertically store the first white elements to a vector. And I want to create a vector which will store the first white elements. After storing the points draw line (as shown in the attached figure) over it.
I have already writen a code in C++, but I don't know how to write it in Matlab.
Here I attach a mask image from where i want to extract the while pixels (First white). For clarifications I have pointed out- what does first whites means in the mask image. Any help is much appreciated to achieve my target.
Hope this is clear.
// C++ code with openCV is shown below:
std::vector<int> firstWhite; // std::vector is a sequence container that encapsulates dynamic size arrays
for(int i=0; i<80; i++)
{
for(int j=0; j<img.rows; j++)
{
if(mask.at<uchar>(cv::Point(i,j)) != 0)
{
firstWhite.push_back(j);
j = 10000; // for example I have 10000 points in the mask image. I need quite fast access to every point.It is much more efficient to allocate too much memory than letting an array grow.
}
}
}
cv::line(img,cv::Point(0,firstWhite[0]),cv::Point(79,firstWhite[79]),cv::Scalar(0,0,0),2 );
// Converting C++ code to matlab. Below is my trial attemp. But unable to achieve the task.
[columns, rows, plane]=size(maskimage);
firstWhite=[]
for i=1: 80
for j=1:rows
if not(maskimage(i,j)==0)
firstWhite(end+1)=j
end
end
end
5 Comments
KSSV
on 17 Jun 2021
Attach the original image.
You can get white pixels using:
I = imread('image.png') ;
I = imcrop(I) ; % pick only the required part of image
I1 = rgb2gray(I) ;
I2 = imbinarize(I1) ;
[y,x] = find(I2) ;
imshow(I)
hold on
plot(x,y,'.r')
Accepted Answer
Walter Roberson
on 17 Jun 2021
iminarize(), bwareafilt()
After that if your binary image is BW, then
first_white_row_idx = sum(cumprod(~BW,1)) + 1
but be careful: rows that have no white at all will show up with output one more than the number of rows
The code above is a vectorized way of find() of the first non-zero pixel for each column. Black is turned to 1's, cumprod that so that the leading 1's on a column are kept but the first 0 stops the run, sum; that gives you the number of 1's before the first 0, which is by construction the number of black pixels before the first white pixel. Add 1 to get the index of the first white pixel.
9 Comments
Walter Roberson
on 18 Jun 2021
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/656085/image.jpeg';
Input_Originalimage = imread(filename); % Step 1: give original image as an input
Crop_image = imcrop(Input_Originalimage,[360 270 306 185]); % Step 2: Crop the original image
imshow(Crop_image)
[height, width, plane] = size(Crop_image);
R= Crop_image(:,:,1); % take the red channel of Crop_image
G=Crop_image(:,:,2); % take the green channel of Crop_image
B=Crop_image(:,:,3); % take the blue channel of Crop_image
mask = R > 130 & R < 150 & G > 150 & G < 180 & B > 110 & B < 150;
mask = bwareafilt(mask, [50 inf]);
figure; imshow(mask); % this is how I calculated a mask image
firstWhite = zeros(1,width);
for col = 1 : width
fw = find(mask(:,col),1);
if isempty(fw)
firstWhite(col) = nan;
else
firstWhite(col) = fw;
end
end
hold on
plot(firstWhite, 'y', 'linewidth', 2);
figure;
dfw = diff(firstWhite);
plot(dfw)
title('difference in firstWhite')
left_edge_x = find(dfw > 3, 1);
left_edge_y = firstWhite(left_edge_x);
right_edge_x = find(dfw < -3, 1, 'last')+1;
right_edge_y = firstWhite(right_edge_x);
figure
imshow(mask)
hold on
plot(firstWhite, 'y', 'linewidth', 2);
plot([left_edge_x, right_edge_x], [left_edge_y, right_edge_y], 'color', [1 .5 0], 'linewidth', 2)
More Answers (0)
See Also
Categories
Find more on Image Processing and Computer Vision 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!