尝试着自己编写houghline代码,也参考了别人的代码,试着实现了一个,如下所示。
但存在一些问题,和opencv自带的效果并不一样,opencv自带(同样参数)的检测出来的直线更多,而我这个少了一些,虽然检测到的都是正确的。那为什么会漏检呢?暂时不知道原因。
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
void HoughM(const Mat &img, vector<Vec2f>&Ve, int theta0,int MinNum);
int main()
{
Mat srcImage = imread("data2.jpg");
if (!srcImage.data)
{
cout << "no srcImage" << endl;
return 0;
}
imshow("orinageImage", srcImage);
Mat midImage, dstImage;
cvtColor(srcImage, midImage, CV_BGR2GRAY);
GaussianBlur(midImage, midImage, Size(3, 3), 0, 0);
Canny(midImage, dstImage, 100, 200,3);
//cvtColor(midImage, dstImage, CV_GRAY2BGR);
imshow("edgeDetect", dstImage);
vector<Vec2f> lines;
//HoughLines(dstImage, lines, 1, CV_PI / 360, 170, 0, 0);
HoughM(dstImage, lines, 1, 170);
float fRate = (float)(CV_PI / 180);
vector<Vec2f>::const_iterator it = lines.begin();
cout << lines.size() << endl;
//while (it != lines.end())
//{
// float rho = (*it)[0];
// float theta = (*it)[1];
// if (theta < CV_PI / 4. || theta>3. * CV_PI / 4)
// {
// Point pt1(rho / cos(theta), 0);
// Point pt2((rho - dstImage.rows*sin(theta)) / cos(theta), dstImage.rows);
// line(dstImage, pt1, pt2, Scalar(100,0,255), 2);
// }
// it++;
// cout << ".";
//}
for (size_t i = 0; i < lines.size(); i++)
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta*fRate), b = sin(theta*fRate);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000 * (-b));
pt1.y = cvRound(y0 + 1000 * (a));
pt2.x = cvRound(x0 - 1000 * (-b));
pt2.y = cvRound(y0 - 1000 * (a));
//if (fabs(a)<0.001)
//{
// pt1.x = pt2.x = cvRound(rho);
// pt1.y = 0;
// pt2.y = dstImage.rows;
//}
//else if (fabs(b)<0.001)
//{
// pt1.y = pt2.y = cvRound(rho);
// pt1.x = 0;
// pt2.x = dstImage.cols;
//}
//else
//{
// pt1.x = 0;
// pt1.y = cvRound(rho / b);
// pt2.x = cvRound(rho / a);
// pt2.y = 0;
//}
line(dstImage, pt1, pt2, Scalar(255, 100, 5), 2, CV_AA);
//line(dstImage,pt1,pt2,Scalar(55,100,195),1,LINE_AA);
}
imshow("HoughLine", dstImage);
waitKey(0);
return 0;
}
void HoughM(const Mat &img, vector<Vec2f>&Ve,int theta0,int MinNum)
{
int width = img.cols;
int height = img.rows;
int iRMax = (int)sqrt(width*width + height*height) + 1;
int iThMax = 360;// theta0;
int *pArray;
pArray = new int[2*iRMax*iThMax];
memset(pArray, 0, sizeof(int)*2*iRMax*iThMax);
float fRate = (float)(CV_PI / 180);
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
if (img.at<unsigned char>(y,x) == 255)
{
for (int iTh = 0; iTh < iThMax; iTh += 1)
{
int iR = (int)(x*cos(iTh*fRate) + y*sin(iTh*fRate));
//if (iR < 0)
// continue;
iR = iR + iRMax;
pArray[2*iRMax*iTh + iR]++;
}
}
}
for (int theta = 0; theta < 360; theta++)
{
for (int r = 0; r < iRMax*2; r++)
{
int thetaL = max(0, theta - 1);
int thetaR = min(359, theta + 1);
int rL = max(0, r - 1);
int rR = min(iRMax*2 - 1, r + 1);
int tmp = pArray[theta*iRMax*2 + r];
//if ((tmp>MinNum)
// && tmp>pArray[thetaL*iRMax * 2 + rL] && tmp>pArray[thetaL*iRMax * 2 + r]
// && (tmp>pArray[thetaL*iRMax * 2 + rR])&& (tmp > pArray[theta*iRMax * 2 + rL])
// && (tmp > pArray[theta*iRMax * 2 + rR])&& (tmp > pArray[thetaR*iRMax * 2 + rL])
// && (tmp > pArray[thetaR*iRMax * 2 + r]) && (tmp > pArray[thetaR*iRMax * 2 + rR])
if ((tmp>MinNum)
&&tmp>pArray[thetaL*iRMax * 2 + r]
&& (tmp >= pArray[theta*iRMax * 2 + rR]) && (tmp > pArray[theta*iRMax * 2 + rL])
&& (tmp >= pArray[thetaR*iRMax * 2 + r]))
{
Vec2f t = Vec2f(float(r-iRMax), float(theta));
Ve.push_back(t);
}
}
}
}