How do I Generate a binary image from first principles?

21 views (last 30 days)
I need to generate a binary image from first principles with my shapes included in the image. I must be able to use the function "bwlabel" to determine the locations of each pixels.My code is below;
  2 Comments
Image Analyst
Image Analyst on 28 May 2015
What's the change from the "shapes" question that you asked earlier this month? If you need a tutorial in how to use bwlabel() and regionprops(), see the Image Segmentation Tutorial in my File Exchange.

Sign in to comment.

Accepted Answer

Thorsten
Thorsten on 28 May 2015
So far you use fill to plot the region. But that's in a figure, not an in an image.
For example, to generate a binary image with of box of 30x40 pixels, you can use
I = zeros(256);
I(10:10+30, I(10:10+40)) = 1;
You have to change your code for the other shapes accordingly, which is unfortunately not that straightforward as for the rectangle.
For a circle, you can use
radius = 10;
[X, Y] = meshgrid(-radius:radius, -radius:radius);
I = zeros(2*radius+1);
I(sqrt(X.^2 + Y.^2) <= radius) = 1;
I hope this will get you started.

More Answers (2)

Image Analyst
Image Analyst on 28 May 2015
Once you have the x,y coordinates, you can simply use poly2mask() to create the binary image.

Walter Roberson
Walter Roberson on 28 May 2015
Start with a blank background:
BinImage = zeros(numberRows, numberColumns);
Rows will correspond to different Y values, columns will correspond to different X values.
A) To construct regions, one way is to write a function, F, to test whether given coordinates are inside or outside the region, returning true or false. Then construct
[Y, X] = ndgrid(1:numberRows, 1:numberColumns);
Then if the function was able to be vectorized (recommended strongly!)
was_in_region = F(X,Y); %returning array of true / false
If you were not able to vectorize it (dang!) then
was_in_region = arrayfun(@F, X, Y); %will call it a pair at a time
Then paint in it into what you have been building up:
BinImage = BinImage | was_in_region;
B) To draw a line, you set the array elements along the line to be true. You can work with trig, sine and cosine and tangent to find slopes.
As a first approximation for straight lines, you can use the old y = m*x + b formula, and increment x by 1 each time, and round(y) to get the array index. You will find that in practice that looks bad on any line outside the range of +/- 45 degrees. So what you should do in practice is find the desired endpoints of the straight line segments, and use Bresenham's Line Algorithm
For curves, what you do is generate a bunch of points along the curves, and join the points with straight line segments. The closer together you generate the points, the smoother the curve will look, but the more line segments you will need to draw.
C) If you are drawing the same shape multiple times in the same orientation, it can be worth pre-computing the endpoints (or several points on the curve) for the shape centered around a mathematical origin and mathematically one unit high. Then when you want to draw it a specific number of units high, multiply all of the representative coordinates by the new height that you want, and then add to all of the coordinate pairs the offset to move the center to where you want it.
For example,
[cx, cy] = circle(15); %generates 15 points around a unit circle
%now generate the circle as radius 78, centered at (144, 203)
newx = cx * 78 + 144;
newy = cy * 78 + 203;

Community Treasure Hunt

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

Start Hunting!