Find Black Squares/Rectangles in Image with C# -
i want find small black squares/rectangles in scanned sheet to:
- deskewing image if needed.
- remove white page margin.
input image: sample image 1 http://us.cdn.persiangig.com/preview/ii2jf6/2.jpg
output image: sample image 2 http://us.cdn.persiangig.com/preview/9ntpnc/1.jpg
my code find square is:
bitmap pic =(bitmap) picturebox1.image; // create filter aforge.imaging.filters.median medianfilter = new aforge.imaging.filters.median(); // apply filter medianfilter.applyinplace(pic); bitmap grayimage; if (pic.pixelformat != pixelformat.format16bppgrayscale && pic.pixelformat != pixelformat.format8bppindexed) { aforge.imaging.filters.grayscale grayscalefilter = new aforge.imaging.filters.grayscale(0.2125, 0.7154, 0.0721); grayimage = grayscalefilter.apply((bitmap)picturebox1.image); } else { grayimage = pic; } // black & white: threshold(ref grayimage, convert.toint32(textbox1.text), convert.toint32(textbox1.text)); // invert filter invert invertfilter = new invert(); // apply filter invertfilter.applyinplace(grayimage); // edge detector filter differenceedgedetector edgedetectorfilter = new differenceedgedetector(); // apply filter edgedetectorfilter.applyinplace(grayimage); // create filter dilatation dilatationfilter = new dilatation(); // apply filter dilatationfilter.applyinplace(grayimage);
finding object(square/rectangle) in image:
// lock image bitmapdata bitmapdata = grayimage.lockbits(new rectangle(0, 0, grayimage.width, grayimage.height), imagelockmode.readwrite, grayimage.pixelformat); // step 2 - locating objects blobcounter blobcounter = new blobcounter(); blobcounter.filterblobs = true; blobcounter.minheight = 10; //*-*-*-*- blobcounter.minwidth = 10; blobcounter.maxheight = 50; blobcounter.maxwidth = 50; blobcounter.processimage(bitmapdata); blob[] blobs = blobcounter.getobjectsinformation(); grayimage.unlockbits(bitmapdata); // step 3 - check objects' type , highlight simpleshapechecker shapechecker = new simpleshapechecker(); graphics g = graphics.fromimage(pic); pen redpen = new pen(color.red, 2); // quadrilateral pen bluepen = new pen(color.blue, 2); // triangle (int = 0, n = blobs.length; < n; i++) { list<intpoint> edgepoints = blobcounter.getblobsedgepoints(blobs[i]); list<intpoint> corners; // triangle or quadrilateral if (shapechecker.isquadrilateral(edgepoints, out corners)) { // sub-type polygonsubtype subtype = shapechecker.checkpolygonsubtype(corners); pen pen; if (subtype == polygonsubtype.square) { pen = (corners.count == 4) ? bluepen : redpen; g.drawpolygon(pen, topointsarray(corners)); } } } redpen.dispose(); bluepen.dispose(); g.dispose(); picturebox1.image = pic;
problem low accuracy on detecting squares , rectangles!!!
how can solve problem?
if can use opencv quite easy. use hough transform , find peaks in output. correspond straight lines in input.
if can't use opencv, you'll need implement yourself. here's started.
https://en.wikipedia.org/?title=hough_transform
edit
as anders gustafsson points out in comment below, hough transform available in aforge .net implementing isn't necessity.
http://www.aforgenet.com/framework/features/hough_transformation.html
Comments
Post a Comment