Robust edge detection OpenCV
I have been using this method to find a card and crop it out of the image:
void findCardAndCrop(Mat& bw,Mat& outerBox)
{
// Remove noise
GaussianBlur(bw, bw, cv::Size(11,11), 0);
adaptiveThreshold(bw, outerBox, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 101, 16);
bitwise_not(outerBox, outerBox);
Mat kernel = (Mat_<uchar>(3,3) << 0,1,0,1,1,1,0,1,0);
dilate(outerBox, outerBox, kernel);
//int count=0;
int max=-1;
cv::Point maxPt;
for(int y=0;y<outerBox.size().height;y++)
{
uchar *row = outerBox.ptr(y);
for(int x=0;x<outerBox.size().width;x++)
{
if(row[x]>=128)
{
int area = floodFill(outerBox, cv::Point(x,y), 64);
if(area>max)
{
maxPt = cv::Point(x,y);
max = area;
}
}
}
}
floodFill(outerBox, maxPt, CV_RGB(255,255,255));
for(int y=0;y<outerBox.size().height;y++)
{
uchar *row = outerBox.ptr(y);
for(int x=0;x<outerBox.size().width;x++)
{
if(row[x]==64 && x!=maxPt.x && y!=maxPt.y)
{
int area = floodFill(outerBox, cv::Point(x,y), CV_RGB(0,0,0));
}
}
}
erode(outerBox, outerBox, kernel);
vector<Vec2f> lines;
HoughLines(outerBox, lines, 1, CV_PI/180, 1200);
mergeRelatedLines(&lines, outerBox);
for(int i=0;i<lines.size();i++)
{
drawLine(lines[i], outerBox, CV_RGB(0,0,128));
}
Vec2f topEdge = Vec2f(1000,1000); //double topYIntercept=100000;//, topXIntercept=0;
Vec2f bottomEdge = Vec2f(-1000,-1000); //double bottomYIntercept=0;//, bottomXIntercept=0;
Vec2f leftEdge = Vec2f(1000,1000); double leftXIntercept=100000;//, leftYIntercept=0;
Vec2f rightEdge = Vec2f(-1000,-1000); double rightXIntercept=0;//, rightYIntercept=0;
for(int i=0;i<lines.size();i++)
{
Vec2f current = lines[i];
float p=current[0];
float theta=current[1];
if(p==0 && theta==-100)
continue;
double xIntercept, yIntercept;
xIntercept = p/cos(theta);
yIntercept = p/(cos(theta)*sin(theta));
if(theta>CV_PI*80/180 && theta<CV_PI*100/180)
{
if(p<topEdge[0])
topEdge = current;
if(p>bottomEdge[0])
bottomEdge = current;
//printf("X: %f, Y: %f\n", xIntercept, yIntercept);
}
else if(theta<CV_PI*10/180 || theta>CV_PI*170/180)
{
/*if(p<leftEdge[0])
leftEdge = current;
if(p>rightEdge[0])
rightEdge = current;*/
if(xIntercept>rightXIntercept)
{
rightEdge = current;
rightXIntercept = xIntercept;
}
else if(xIntercept<=leftXIntercept)
{
leftEdge = current;
leftXIntercept = xIntercept;
}
}
}
drawLine(topEdge, outerBox, CV_RGB(0,0,0));
drawLine(bottomEdge, outerBox, CV_RGB(0,0,0));
drawLine(leftEdge, outerBox, CV_RGB(0,0,0));
drawLine(rightEdge, outerBox, CV_RGB(0,0,0));
cv::Point left1, left2, right1, right2, bottom1, bottom2, top1, top2;
int height=outerBox.size().height;
int width=outerBox.size().width;
if(leftEdge[1]!=0)
{
left1.x=0; left1.y=leftEdge[0]/sin(leftEdge[1]);
left2.x=width; left2.y=-left2.x/tan(leftEdge[1]) + left1.y;
}
else
{
left1.y=0; left1.x=leftEdge[0]/cos(leftEdge[1]);
left2.y=height; left2.x=left1.x - height*tan(leftEdge[1]);
}
if(rightEdge[1]!=0)
{
right1.x=0; right1.y=rightEdge[0]/sin(rightEdge[1]);
right2.x=width; right2.y=-right2.x/tan(rightEdge[1]) + right1.y;
}
else
{
right1.y=0; right1.x=rightEdge[0]/cos(rightEdge[1]);
right2.y=height; right2.x=right1.x - height*tan(rightEdge[1]);
}
bottom1.x=0; bottom1.y=bottomEdge[0]/sin ...
add a comment