Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 高亮显示通过hough变换找到的线-OPENCV_Matlab_Opencv_Hough Transform - Fatal编程技术网

Matlab 高亮显示通过hough变换找到的线-OPENCV

Matlab 高亮显示通过hough变换找到的线-OPENCV,matlab,opencv,hough-transform,Matlab,Opencv,Hough Transform,在Matlab中,通过结合hough变换、hough峰值和hough线,可以在原始图像中显示检测到的线 这可以在下图中显示(使用Matlab的houghlines帮助中的示例代码生成)。检测到绿线。蓝色的是最长的: 我在生成的一张简单的合成图像(几个正方形等)上运行了cv::HoughLines。图片附于此处: 相关代码部分为: cv::vector<cv::Vec2f> lines; cv::HoughLines(I_BW, lines, 1, CV_PI/180,200);

在Matlab中,通过结合hough变换、hough峰值和hough线,可以在原始图像中显示检测到的线

这可以在下图中显示(使用Matlab的houghlines帮助中的示例代码生成)。检测到绿线。蓝色的是最长的:

我在生成的一张简单的合成图像(几个正方形等)上运行了cv::HoughLines。图片附于此处:

相关代码部分为:

cv::vector<cv::Vec2f> lines;
cv::HoughLines(I_BW, lines, 1, CV_PI/180,200);
cv::Mat linesMat ( lines, true );
cv::矢量线;
cv::HoughLines(I_BW,lines,1,cv_PI/180200);
cv::Mat linesMat(线条,真实);
查看linesMat矩阵(我将其转换为这种形式,以便使用image watch查看数据),同时运行for循环在边缘图像上添加红线,我看到ρ和θ按图像中最长直线的长度排序

我的输出是:

线条是图像的整个宽度(或高度)。我怎样才能像在Matlab示例中那样显示实际的线呢? 我可以从ρ+θ回到x和y,但我必须以某种方式将它们与检测到的边缘等联系起来-也许有一种简单的方法可以做到这一点,但我没有


谢谢

您要寻找的是概率霍夫变换。在OpenCV中,它可以在下面找到。

塔乌菲克是正确的,我对他的答案投了赞成票。 在我读他的评论之前,我在OpenCV 2计算机视觉应用程序编程食谱中找到了答案

我选择我的答案作为答案,因为它更完整,以备将来参考

@塔乌菲克-再次感谢你,伙计

我将发布一个可能对其他人有用的代码片段(基于我在烹饪书中找到的解决方案。我只是编写了简短的版本,而不是烹饪书中优雅的类实现)

我还在这里添加了一个我编写的小函数,用于计算CDF,该函数用于在canny的Matlab实现中查找canny边缘检测器的高阈值和低阈值,结果很好。通常我在边缘检测之前也会进行高斯模糊(如Matlab中的canny.m中所示),但是附加的图像是综合完美的(没有噪声),因此在这里是多余的。 我选择了一个较高的最小投票值(“阈值”),因此只会找到4条长线

我们将从主函数中的代码开始:

cv::Mat image = cv::imread("shapes.jpg");
int bins = 256;
cv::Mat cdf = getGrayCDF(image,bins);
cv::Mat diffy = cdf>0.7;
cv::Mat NonZero_Locations;   // output, locations of non-zero pixels 
cv::findNonZero(diffy, NonZero_Locations);
double highThreshold = double((NonZero_Locations.at<cv::Point>(0).y))/bins;
double lowThreshold = 0.4*highThreshold;
cv::Mat contours;
// cv::GaussianBlur( image, contours, cv::Size(7,7),2 ); // NOT REQUIRED HERE. Syhnthetic image
cv::Canny( image, contours, lowThreshold*bins, highThreshold*bins);
std::vector<cv::Vec4i> lines;
double rho = 1; // delta_rho resolution
double theta = CV_PI/180; // delta_theta resolution
int threshold = 300; // threshold number of votes , I SET A HIGH VALUE TO FIND ONLY THE LONG LINES
double minLineLength = 0; // min length for a line
double maxLineGap = 2; // max allowed gap along the line
cv::HoughLinesP(contours,lines, rho, theta, threshold, minLineLength, maxLineGap); // running probabilistic hough line
if (image.channels()!=3) {cv::cvtColor(image,image,CV_GRAY2BGR);} // so we can see the red lines
int line_thickness = 2;
cv::Scalar color=cv::Scalar(0,0,255);
std::vector<cv::Vec4i>::const_iterator iterator_lines = lines.begin();
while (iterator_lines!=lines.end()) {
    cv::Point pt1((*iterator_lines)[0],(*iterator_lines)[1]);
    cv::Point pt2((*iterator_lines)[2],(*iterator_lines)[3]);
    cv::line( image, pt1, pt2, color, line_thickness);
    ++iterator_lines;
}
cv::imshow("found lines", image); cvWaitKey(0); cv::destroyWindow("found lines");
cv::Mat getGrayCDF(cv::Mat Input, int histSize){
cv::Mat InputGray = Input.clone();
if (InputGray.channels()!=1) {cv::cvtColor(Input,InputGray,CV_BGR2GRAY);}
float range[] = { 0, histSize  } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
cv::Mat hist;
calcHist( &InputGray, 1, 0, cv::Mat(), hist, 1, &histSize , &histRange, uniform, accumulate );
for (int i = 1; i < hist.rows; i++) {
    float* data = hist.ptr<float>(0);
    data[i] += data[i-1];
}
return hist/(InputGray.total()); // WE NOW HAVE A *NORMALIZED* COMPUTED CDF!
}
cv::Mat image=cv::imread(“shapes.jpg”);
int bins=256;
cv::Mat cdf=getGrayCDF(图像、箱子);
cv::Mat diffy=cdf>0.7;
cv::Mat非零位置;//输出,非零像素的位置
cv::findNonZero(不同的非零位置);
double highThreshold=double((0.y处的非零位置))/bin;
双低阈值=0.4*高阈值;
cv::垫状轮廓;
//cv::高斯模糊(图像,轮廓,cv::大小(7,7),2);//这里不需要。合成影像
cv::Canny(图像、轮廓、低阈值*箱、高阈值*箱);
std::矢量线;
双rho=1;//delta_-rho分辨率
双θ=CV_PI/180;//δθ分辨率
整数阈值=300;//阈值投票数,我设置了一个高值,只找到长线
双minLineLength=0;//线的最小长度
双maxLineGap=2;//沿线允许的最大间隙
cv::HoughLinesP(等高线、直线、菱形、θ、阈值、最小线长度、最大线间距);//运行概率hough线
如果(image.channels()!=3){cv::cvtColor(image,image,cv_GRAY2BGR);}//那么我们可以看到红线
int line_厚度=2;
cv::Scalar color=cv::Scalar(0,0255);
std::vector::const_迭代器迭代器_lines=lines.begin();
while(迭代器_line!=line.end()){
cv::点pt1((*迭代器_线)[0],(*迭代器_线)[1]);
cv::点pt2((*迭代器_线)[2],(*迭代器_线)[3]);
cv::线条(图像、pt1、pt2、颜色、线条厚度);
++迭代器线;
}
cv::imshow(“找到的线”,图像);cvWaitKey(0);cv::destroyWindow(“找到的行”);
我将以计算简单灰度累积分布函数的函数结束:

cv::Mat image = cv::imread("shapes.jpg");
int bins = 256;
cv::Mat cdf = getGrayCDF(image,bins);
cv::Mat diffy = cdf>0.7;
cv::Mat NonZero_Locations;   // output, locations of non-zero pixels 
cv::findNonZero(diffy, NonZero_Locations);
double highThreshold = double((NonZero_Locations.at<cv::Point>(0).y))/bins;
double lowThreshold = 0.4*highThreshold;
cv::Mat contours;
// cv::GaussianBlur( image, contours, cv::Size(7,7),2 ); // NOT REQUIRED HERE. Syhnthetic image
cv::Canny( image, contours, lowThreshold*bins, highThreshold*bins);
std::vector<cv::Vec4i> lines;
double rho = 1; // delta_rho resolution
double theta = CV_PI/180; // delta_theta resolution
int threshold = 300; // threshold number of votes , I SET A HIGH VALUE TO FIND ONLY THE LONG LINES
double minLineLength = 0; // min length for a line
double maxLineGap = 2; // max allowed gap along the line
cv::HoughLinesP(contours,lines, rho, theta, threshold, minLineLength, maxLineGap); // running probabilistic hough line
if (image.channels()!=3) {cv::cvtColor(image,image,CV_GRAY2BGR);} // so we can see the red lines
int line_thickness = 2;
cv::Scalar color=cv::Scalar(0,0,255);
std::vector<cv::Vec4i>::const_iterator iterator_lines = lines.begin();
while (iterator_lines!=lines.end()) {
    cv::Point pt1((*iterator_lines)[0],(*iterator_lines)[1]);
    cv::Point pt2((*iterator_lines)[2],(*iterator_lines)[3]);
    cv::line( image, pt1, pt2, color, line_thickness);
    ++iterator_lines;
}
cv::imshow("found lines", image); cvWaitKey(0); cv::destroyWindow("found lines");
cv::Mat getGrayCDF(cv::Mat Input, int histSize){
cv::Mat InputGray = Input.clone();
if (InputGray.channels()!=1) {cv::cvtColor(Input,InputGray,CV_BGR2GRAY);}
float range[] = { 0, histSize  } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
cv::Mat hist;
calcHist( &InputGray, 1, 0, cv::Mat(), hist, 1, &histSize , &histRange, uniform, accumulate );
for (int i = 1; i < hist.rows; i++) {
    float* data = hist.ptr<float>(0);
    data[i] += data[i-1];
}
return hist/(InputGray.total()); // WE NOW HAVE A *NORMALIZED* COMPUTED CDF!
}
cv::Mat getGrayCDF(cv::Mat Input,int histSize){
cv::Mat InputGray=Input.clone();
如果(InputGray.channels()!=1){cv::cvtColor(Input,InputGray,cv_BGR2GRAY);}
浮动范围[]={0,histSize};
常量浮点*histRange={range};
布尔一致=真;布尔累积=假;
cv::Mat hist;
calcHist(&InputGray,1,0,cv::Mat(),hist,1,&histSize,&histRange,uniform,accumulate);
对于(int i=1;i
我对上述代码段的解决方案是:

希望你觉得这个有用