我想在两行之间裁剪图像,如下图所示。但HoughLinesP
并未充分认识到底线。
由于侵蚀,底线点并没有真正的边缘,但这很重要吗?
如何检测底线,然后根据这两行裁剪图像?
原始图片:
已处理的图片:
Canny edged:
检测到的行:
线路检测代码:
Mat dst, cdst,src2;
cv::blur( src, src2, cv::Size(5,5) );
Canny(src2, dst, 150, 300, 5);
cvtColor(dst, cdst, CV_GRAY2BGR);
//Mat original = imread("final_sample1.png",0);
vector<Vec4i> lines;
HoughLinesP(dst, lines, 1, 2*CV_PI/180, 100,1000, 50 );
用于显示行:
for( size_t i = 0; i < lines.size(); i++ )
{
Vec4i l = lines[i];
// oran = float(l[1] / col_size );
double angle = atan2(l[3] - l[1], l[2] - l[0]) * 180.0 / CV_PI;
if(angle < 5 && angle >=-5 ){
//if(1){
cout << l[0] << "," << l[1] << "," << l[2] << "," << l[3] << endl;
line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
}
}
编辑:
对于线检测,应用自适应阈值处理原始图像可以得到更可靠的结果。
adaptiveThreshold(img,adaptiveTresholded,255,ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY,75,15);
我测试了20个行数不同的样本,感谢Micka的修改,我得到了很好的结果。为了检测正确的行,我放了一个if语句。
“ratio”变量是图像的y1 /行大小。并检查线角度以防止 无关紧要的。
for( size_t i = 0; i < lines.size(); i++ )
{
Vec4i l = lines[i];
raito = float(l[1] / row_size );
double angle = atan2(l[3] - l[1], l[2] - l[0]) * 180.0 / CV_PI;
if(angle < 10 && angle >=- 10 && ratio > 0.15 && ratio< 0.8){
//if(1){
cout <<"Here: " << l[0] << "," << l[1] << "," << l[2] << "," << l[3] <<
", Oran: " << oran << endl;
line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3);
}
}
答案 0 :(得分:1)
使用你的图像和这个代码(基本上你的,但减少了最大线间隙,并使用一些扩张实际上使连接的straigt部分从非直线底线:
int main()
{
cv::Mat input = cv::imread("../inputData/LongLine.jpg");
cv::Mat gray;
cv::cvtColor(input,gray,CV_BGR2GRAY);
// threshold because of loaded jpeg artifacts
cv::Mat edges = gray > 100;
cv::dilate(edges, edges, cv::Mat());
cv::dilate(edges, edges, cv::Mat());
cv::dilate(edges, edges, cv::Mat());
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(edges, lines, 1, 2*CV_PI/180, 100,1000, 10 );
for( size_t i = 0; i < lines.size(); i++ )
{
cv::Vec4i l = lines[i];
cv::line( input, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(0,0,255), 3);
}
cv::imwrite("../outputData/LongLine.png", input);
cv::resize(input, input, cv::Size(), 0.1, 0.1);
cv::imshow("input",input);
cv::waitKey(0);
return 0;
}
得到这个结果:
对于HoughLinesP,重要的是线条非常直,因为求和线的厚度预计为1.因此,如果累加器仅缺少一个像素,则失败。由于底线与第一条底线不同,这可能是问题所在。
答案 1 :(得分:0)