1 | initial version |
You may want to start using a top hat operation. That will make you get rid of the blurry non black background:
static void Main(string[] args)
{
Image<Gray, byte> image = new Image<Gray, byte>(@"c:\im.png");
int morphOpSize = 5;
StructuringElementEx element =
new StructuringElementEx(
morphOpSize,
morphOpSize,
morphOpSize / 2,
morphOpSize / 2,
Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
Image<Gray, byte> filtered;
filtered = image.MorphologyEx(
element,
Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
1);
ImageViewer.Show(image.ConcateHorizontal(filtered));
}
(Sorry for my emgu dialect.)
Then you may want to use findContours and do away with blobs that are more then e.g. twice as high as they are wide.
2 | No.2 Revision |
You may want to start using a top hat operation. That will make you get rid of the blurry non black background:
static void Main(string[] args)
{
Image<Gray, byte> image = new Image<Gray, byte>(@"c:\im.png");
int morphOpSize = 5;
StructuringElementEx element =
new StructuringElementEx(
morphOpSize,
morphOpSize,
morphOpSize / 2,
morphOpSize / 2,
Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
Image<Gray, byte> filtered;
filtered = image.MorphologyEx(
element,
Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
1);
ImageViewer.Show(image.ConcateHorizontal(filtered));
}
(Sorry for my emgu dialect.)dialect.)
You will get this result:
Then you may want to use findContours and do away with blobs that are more then e.g. twice as high as they are wide.
3 | No.3 Revision |
You may want to start using a top hat operation. That will make you get rid of the blurry non black background:background.
static void Main(string[] args)
{
Image<Gray, byte> image = new Image<Gray, byte>(@"c:\im.png");
int morphOpSize = 5;
StructuringElementEx element =
new StructuringElementEx(
morphOpSize,
morphOpSize,
morphOpSize / 2,
morphOpSize / 2,
Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
Image<Gray, byte> filtered;
filtered = image.MorphologyEx(
element,
Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
1);
ImageViewer.Show(image.ConcateHorizontal(filtered));
}
(Sorry for my emgu dialect.)
You will get this result:
Second step would be binarization. I used a simple threshold, but there is still some work to be done here. Perhaps watersehd could help you.
Then you may want to use findContours and do away with blobs that are more then e.g. twice as high as they are wide.
static void Main(string[] args)
{
Image<Bgr, byte> bgr = new Image<Bgr, byte>(@"k:\tomgoo\im.png");
Image<Gray, byte> gray = bgr.Convert<Gray, byte>();
// Perform top-hat
int morphOpSize = 5;
StructuringElementEx element =
new StructuringElementEx(
morphOpSize,
morphOpSize,
morphOpSize / 2,
morphOpSize / 2,
Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
Image<Gray, byte> filtered;
filtered = gray.MorphologyEx(
element,
Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
1);
// binarize image
double thresh = CvInvoke.cvThreshold(
filtered,
filtered,
100,
255,
THRESH.CV_THRESH_BINARY);
// find and filter out blobs
Contour<Point> contours = filtered.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP);
Contour<Point> cont = contours;
while (cont != null)
{
// Remember the next contour for later and isolate the current one
Contour<Point> next = cont.HNext;
cont.HNext = null;
MCvBox2D minAreaRect = cont.GetMinAreaRect();
if (minAreaRect.size.Height < 1.5 * minAreaRect.size.Width)
{
// Generate random color
CvInvoke.cvDrawContours(
bgr,
cont,
new MCvScalar(255, 0, 0),
new MCvScalar(255, 0, 0),
2,
2,
LINE_TYPE.EIGHT_CONNECTED,
new Point(0, 0));
}
// Now go to the next contour
cont = next;
}
bgr.Save(@"c:\out.png");
}
(Sorry for my emgu dialect.) You will get this result: and
4 | No.4 Revision |
You may want to start using a top hat operation. That will make you get rid of the blurry non black background.
Second step would be binarization. I used a simple threshold, but there is still some work to be done here. Perhaps watersehd could help you.
Then you may want to use findContours and do away with blobs that are more then e.g. twice 1.5 times as high as they are wide.
static void Main(string[] args)
{
Image<Bgr, byte> bgr = new Image<Bgr, byte>(@"k:\tomgoo\im.png");
Image<Gray, byte> gray = bgr.Convert<Gray, byte>();
// Perform top-hat
int morphOpSize = 5;
StructuringElementEx element =
new StructuringElementEx(
morphOpSize,
morphOpSize,
morphOpSize / 2,
morphOpSize / 2,
Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
Image<Gray, byte> filtered;
filtered = gray.MorphologyEx(
element,
Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
1);
// binarize image
double thresh = CvInvoke.cvThreshold(
filtered,
filtered,
100,
255,
THRESH.CV_THRESH_BINARY);
// find and filter out blobs
Contour<Point> contours = filtered.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP);
Contour<Point> cont = contours;
while (cont != null)
{
// Remember the next contour for later and isolate the current one
Contour<Point> next = cont.HNext;
cont.HNext = null;
MCvBox2D minAreaRect = cont.GetMinAreaRect();
if (minAreaRect.size.Height < 1.5 * minAreaRect.size.Width)
{
// Generate random color
CvInvoke.cvDrawContours(
bgr,
cont,
new MCvScalar(255, 0, 0),
new MCvScalar(255, 0, 0),
2,
2,
LINE_TYPE.EIGHT_CONNECTED,
new Point(0, 0));
}
// Now go to the next contour
cont = next;
}
bgr.Save(@"c:\out.png");
}
(Sorry for my emgu dialect.) You will get this result: and
5 | No.5 Revision |
You may want to start using a top hat operation. That will make you get rid of the blurry non black background.
Second step would be binarization. I used a simple threshold, but there is still some work to be done here. Perhaps watersehd watershed could help you.
Then you may want to use findContours and do away with blobs that are more then e.g. 1.5 times as high as they are wide.
static void Main(string[] args)
{
Image<Bgr, byte> bgr = new Image<Bgr, byte>(@"k:\tomgoo\im.png");
Image<Gray, byte> gray = bgr.Convert<Gray, byte>();
// Perform top-hat
int morphOpSize = 5;
StructuringElementEx element =
new StructuringElementEx(
morphOpSize,
morphOpSize,
morphOpSize / 2,
morphOpSize / 2,
Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);
Image<Gray, byte> filtered;
filtered = gray.MorphologyEx(
element,
Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_TOPHAT,
1);
// binarize image
double thresh = CvInvoke.cvThreshold(
filtered,
filtered,
100,
255,
THRESH.CV_THRESH_BINARY);
// find and filter out blobs
Contour<Point> contours = filtered.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP);
Contour<Point> cont = contours;
while (cont != null)
{
// Remember the next contour for later and isolate the current one
Contour<Point> next = cont.HNext;
cont.HNext = null;
MCvBox2D minAreaRect = cont.GetMinAreaRect();
if (minAreaRect.size.Height < 1.5 * minAreaRect.size.Width)
{
// Generate random color
CvInvoke.cvDrawContours(
bgr,
cont,
new MCvScalar(255, 0, 0),
new MCvScalar(255, 0, 0),
2,
2,
LINE_TYPE.EIGHT_CONNECTED,
new Point(0, 0));
}
// Now go to the next contour
cont = next;
}
bgr.Save(@"c:\out.png");
}
(Sorry for my emgu dialect.) You will get this result: and