二值化图像;
利用黑白像素值求差,得到边缘点;
过滤边缘点找到合适区域;
利用cvFitLine2D拟合线。
做的比较粗糙,搜寻时间在10ms左右,希望有研究opencv的朋友斧正。
效果预览:
、
void CvProcess::FindLine(
IplImage* orgImg ,//原始图像
IplImage*runImg,//显示用图像
CvRect rec,//roi
int thredValue,//二值化阈值
int lineAccuracy,//搜索精度
int SearchDirection,//搜索方向
int EdgePolarity)//搜索方式 黑到白 白到黑
{
cvCopy(orgImg,runImg);//原始图像拷贝到显示图像用于显示
IplImage* thrdImg = cvCreateImage(//创建一个单通道二值图像用于各种处理
cvSize(orgImg->width,orgImg->height),
IPL_DEPTH_8U,
1);
//将原始图像转换为单通道灰度图像
cvCvtColor(runImg,thrdImg,CV_BGR2GRAY);
//二值化处理
cvThreshold(
thrdImg,
thrdImg,
thredValue,
255,
CV_THRESH_BINARY);
// cvNamedWindow("");
// cvShowImage("",thrdImg);
if(rec.width>0&&rec.width<IMAGE_WIDTH&&rec.height>0&&rec.width<IMAGE_HEIGHT)//判断是否有适合的ROI区域
{ //设置ROI
cvSetImageROI(runImg,rec);
cvSetImageROI(thrdImg,rec);
//搜索边界
CvPoint2D32f *EdgePoint2D = //用于存储搜索到的所有边界点
(CvPoint2D32f *)malloc((IMAGE_HEIGHT*IMAGE_WIDTH) * sizeof(CvPoint2D32f));
CvPoint2D32f *RelEdgePoint2D =//用于存储搜索到的正确的点
(CvPoint2D32f *)malloc((IMAGE_HEIGHT*IMAGE_WIDTH) * sizeof(CvPoint2D32f));
int EdgePoint2DCount=0;//点计数
int RelEdgePoint2DCount=0; //真实点计数
float *line = new float[4]; //用于画逼近线
byte ftData=0,secData=0; //搜索边界点所需资源
//得到ROI区域内的搜索线
std::vector<CLine> searchlines = GetRecLines(rec,lineAccuracy,SearchDirection);
switch(SearchDirection)//搜索方向
{
case TB :
//上到下纵向搜索
for (int i=0;i<thrdImg->roi->width;i++)
{
for (int j=0;j<thrdImg->roi->height-1;j++)
{ //上下搜索所有的差值大于200的点
ftData=CV_IMAGE_ELEM(thrdImg,uchar,thrdImg->roi->yOffset+j,thrdImg->roi->xOffset+