【问题标题】:Scan picture and detect lines扫描图片并检测线条
【发布时间】:2013-02-10 03:57:03
【问题描述】:

我的任务如下:“使用 cvFilter2D 函数和合适的内核来扫描图片,然后只保留 +- 45 度和 +- 60 度的线”。

谁能给我一些线索,尤其是如何计算内核?

【问题讨论】:

  • 你需要“学习 OpenCV” 这在第 6 章中有介绍。

标签: c++ opencv feature-detection


【解决方案1】:

对不起,我的回复晚了!我已经完成了这个任务!首先,再次感谢您,佩凡诺夫!感谢您的参考链接,我找到了解决问题的方法! 这是我的代码:

// Image Transforms.cpp : Defines the entry point for the console application.

/*The purpose of this program is to detect lines which are +-45 degree and +- 60 degree from a binary picture.*/
 #include "stdafx.h"
 #include "cv.h"
 #include "highgui.h" 

int _tmain(int argc, _TCHAR* argv[])
{
//IplImage* src = cvLoadImage("C:\\Users\\USER\\Desktop\\black white 1.jpg");
IplImage* src = cvLoadImage("C:\\Users\\USER\\Desktop\\line detection 4.png");

cvNamedWindow("src", CV_WINDOW_NORMAL);
cvShowImage("src", src);    

IplImage* DstSum = cvCreateImage(cvGetSize(src),src->depth, 3);
IplImage* Dst45 = cvCreateImage(cvGetSize(src),src->depth, 3);
IplImage* Dst135 = cvCreateImage(cvGetSize(src),src->depth, 3);
IplImage* Dst60 = cvCreateImage(cvGetSize(src),src->depth, 3);
IplImage* Dst120 = cvCreateImage(cvGetSize(src),src->depth, 3);

/*double Ker0 [] = { -0.1,-0.1,-0.1,-0.1,-0.1,
                0, 0, 0, 0, 0, 0,
                0.2,0.2,0.2,0.2,0.2,
                0, 0, 0, 0, 0, 0,
                -0.1,-0.1,-0.1,-0.1,-0.1
                };
double Ker90 [] = {-0.1,0,0.2,0,-0.1,
                -0.1,0,0.2,0,-0.1,
                -0.1,0,0.2,0,-0.1,
                -0.1,0,0.2,0,-0.1,
                -0.1,0,0.2,0,-0.1
                }; */

double Ker45[]={
                 0,-0.1,-0.1, 0, 0.2,
                -0.1,-0.1, 0, 0.2, 0,
                -0.1, 0, 0.2, 0,-0.1,
                 0, 0.2, 0,-0.1,-0.1,
                0.2, 0,-0.1,-0.1, 0
                };// 45 degree 

CvMat Kernel45=cvMat(5, 5, CV_64FC1,Ker45);

double Ker135[]={
        0.2, 0,-0.1,-0.1, 0,
        0, 0.2, 0,-0.1,-0.1,
        -0.1, 0, 0.2, 0,-0.1,
        -0.1,-0.1, 0, 0.2, 0,
        0,-0.1,-0.1, 0, 0.2
        };// 135 degree 

CvMat Kernel135=cvMat(5, 5, CV_64FC1,Ker135);

double Ker120[] = {0,0,0,0,0,0,0,
                  1/7,0.25/7,0,0,0,0,0,
                  0,0.75/7,0.75/7,0.25/7,0,0,0,
                  0,0,0,0.75/7,0.6/7,0.25/7,0,
                  0,0,0,0,0.4/7,0.75/7,1/7,
                  0,0,0,0,0,0,0,
                  0,0,0,0,0,0,0
                };//120 degree
CvMat Kernel120=cvMat(7, 7, CV_64FC1,Ker120);

double Ker60[] = {0,0,0,0,1/7,0,0,
                  0,0,0,0.25/7,0.75/7,0,0,
                  0,0,0,0.6/7,0.4/7,0,0,
                  0,0,0.25/7,0.75/7,0,0,0,
                  0,0,0.75/7,0.25/7,0,0,0,
                  0,0.25/7,0.75/7,0,0,0,0,
                  0,1/7,0,0,0,0,0
                };//60 degree

CvMat Kernel60=cvMat(7, 7, CV_64FC1,Ker60);

cvFilter2D(src,Dst60,&Kernel60,cvPoint(-1,-1));
cvThreshold(Dst60,Dst60,100,255,CV_THRESH_BINARY);

cvFilter2D(src,Dst120,&Kernel120,cvPoint(-1,-1));
cvThreshold(Dst120,Dst120,100,255,CV_THRESH_BINARY);

cvFilter2D(src,Dst45,&Kernel45,cvPoint(-1,-1));
cvThreshold(Dst45,Dst45,200,255,CV_THRESH_BINARY);

cvFilter2D(src,Dst135,&Kernel135,cvPoint(-1,-1));
cvThreshold(Dst135,Dst135,200,255,CV_THRESH_BINARY);

cvAdd(Dst45,Dst60,DstSum,NULL);
cvAdd(Dst135,DstSum,DstSum,NULL);
cvAdd(Dst120,DstSum,DstSum,NULL);

cvNamedWindow("dst", CV_WINDOW_NORMAL);
cvShowImage("dst", DstSum);

cvReleaseImage(&DstSum);

cvWaitKey(0);

cvReleaseImage(&src);

cvDestroyWindow("src");
cvDestroyWindow("dst"); 

return 0;

}

结果如下:

【讨论】:

    【解决方案2】:

    你需要一点微积分。 我假设您想创建一个线路内核。所以你需要知道如何创建一条线。

    http://courses.engr.illinois.edu/ece390/archive/archive-f2000/mp/mp4/anti.html 掌握了很多技巧。

    最后,对内核中的所有像素求和,并将它们归一化,使它们加起来为 1。

    【讨论】:

    • 谢谢!但是您的意思是“将它们标准化,使它们加起来为 1”?
    • 嗯,你有一个一定大小的内核,例如一个 5x5 的内核,填充了 1 和 0(在没有抗锯齿的情况下)。如果将内核中的所有数字相加,例如,它们可能加起来为 13。这不应该发生,因为在将内核应用于图像后,亮度将增加 13 倍。因此,当您制作内核时,请确保获得内核中像素的总和并将每个像素除以该数字,这样内核将被归一化。
    • 谢谢! ^~^!似乎如果线条足够粗,那条线的结果将包括 2 条边缘线!我读过一些网页,他们说我们必须在应用内核之前进行“骨架化”!你能告诉我怎么做吗?
    猜你喜欢
    • 2017-05-20
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 2022-11-08
    • 2014-11-17
    相关资源
    最近更新 更多