I used this code for segmentation, I'm trying to detect pixels one by one because my object is a binary, not a grayscale. when i run the program, it draws 2 object. The first object is successfully drawn (object still has a black color and a red rectangle), but the second object fails get drawn. Screenshot is here. Please help me, why does this happen?
#region Edge Detection
private void btnSegmentasi_Click(object sender, EventArgs e)
{
Segments = new List<ImageSegment>();
Bitmap bmp = (Bitmap)pb2.Image;
imageArea = new Rectangle(0, 0, pb2.Image.Width - 1, pb2.Image.Height - 1);
for (int y = 0; y < pb2.Image.Height; y++)
{
for (int x = 0; x < pb2.Image.Width; x++)
{
bool skip = false;
foreach (ImageSegment segment in Segments)
{
if (pointIsInRect(x, y, segment.Rect))
{
skip = true;
break;
}
}
if (skip) continue;
Color warna = bmp.GetPixel(x, y);
if (warna.G == 0)
startEdgeDetection(x, y, ref bmp);
}
}
DGVProses.DataSource = Segments;
if (Segments.Count > 0)
{
Graphics g = pb2.CreateGraphics();
Rectangle[] rects = (from theSegment in Segments select theSegment.Rect).ToArray();
g.DrawRectangles(new Pen(Brushes.Red), rects);
g.Dispose();
}
}
private void startEdgeDetection(int x, int y, ref Bitmap bmp)
{
Point startPoint = new Point(x, y);
Point currPoint = new Point(x, y);
int sudut = 180;
int xMin = x, yMin = y, xMax = x, yMax = y;
do
{
sudut -= 45;
Point offset = angleToPoint(ref sudut);
Point trialPoint = new Point(currPoint.X + offset.X, currPoint.Y + offset.Y);
if (!pointIsInRect(trialPoint.X, trialPoint.Y, imageArea))
continue;
Color theColor = bmp.GetPixel(trialPoint.X, trialPoint.Y);
if (theColor.G == 0)
{
currPoint = trialPoint;
sudut -= 180;
if (currPoint.X > xMax)
xMax = currPoint.X;
else if (currPoint.X < xMin)
xMin = currPoint.X;
if (currPoint.Y > yMax)
yMax = currPoint.Y;
else if (currPoint.Y < yMin)
yMin = currPoint.Y;
if (sudut < 0)
sudut += 360;
if (currPoint == startPoint && sudut == 180)
break;
}
}
while (!(currPoint == startPoint && sudut == 180));
Rectangle r = new Rectangle(xMin, yMin, xMax - xMin + 1, yMax - yMin + 1);
Bitmap newImage = new Bitmap(r.Width + 2, r.Height + 2);
using (Graphics g = Graphics.FromImage(newImage))
{
g.FillRectangle(Brushes.White, 0, 0, newImage.Width, newImage.Height);
g.DrawImage(bmp, new Rectangle(1, 1, r.Width, r.Height), r, GraphicsUnit.Pixel);
g.Dispose();
}
Segments.Add(new ImageSegment(r, newImage));
}
private Point angleToPoint(ref int sudut)
{
if (sudut < 0)
sudut += 360;
switch (sudut)
{
case 135: return new Point(-1, -1);
case 90: return new Point(0, -1);
case 45: return new Point(1, -1);
case 0: return new Point(1, 0);
case 315: return new Point(1, 1);
case 270: return new Point(0, 1);
case 225: return new Point(-1, 1);
default: return new Point(-1, 0);
}
}
private bool pointIsInRect(int x, int y, Rectangle rect)
{
if (x < rect.X)
return false;
if (x > rect.X + rect.Width)
return false;
if (x < rect.Y)
return false;
if (x > rect.Y + rect.Height)
return false;
return true;
}
#endregion