提取线激光的几种基础方法
极值法:
首先将图像转化为灰度图,然后按行寻找每一行的亮度最大值,在这里还加入了一个阈值threshod,也可以不加
Mat Max_Value(Mat Src)
{
Mat img = Src.clone();
Mat Laser_Line(Src.rows, Src.cols, CV_8UC1);
cvtColor(Src, img, CV_BGR2GRAY);
int h = img.rows, w = img.cols;
int index = 0;
//这里设置一个阈值,每一行的最大值不一定是激光线,大于这个阈值才认为是激光线
int threshod = 170;
for (int i = 0; i < h; i++)
{
double max_row = 0;
for (int j = 0; j < w; j++)
{
if (img.at<uint8_t>(i, j) > max_row)
{
max_row = img.at<uint8_t>(i, j);
index = j;
}
}
if (max_row > threshod)
Laser_Line.at<uint8_t>(i, index) = 255;
}
imshow("极值法", Laser_Line);
waitKey(0);
return Laser_Line;
}
阈值法:
从图像的左右两侧向中间寻找激光条的左右边界,然后找到左右边界的中点即为激光线的中心
Mat Fixed_Threshold(Mat Src)
{
Mat img = Src.clone();
Mat Laser_Line(Src.rows, Src.cols, CV_8UC1);
int index1 = 0;
int index2 = 0;
int threshod = 170;
int h = img.rows, w = img.cols;
cvtColor(img, img, CV_BGR2GRAY);
//threshold(img, img, threshod, 255, THRESH_BINARY);
for (int i = 0; i < h; i++)
{
//从左侧开始向右查找
for (int j = 0; j < w; j++)
{
if ((img.at<uint8_t>(i, j) > threshod))
{
index1 = j;
cout << i << " index1: " << index1 << " ";
break;
}
}
//从右侧开始向左查找
for (int j = w - 1; j >= 0; j--)
{
if ((img.at<uint8_t>(i, j) > threshod))
{
index2 = j;
cout << "index2: " << index2 << endl;
break;
}
}
if ((index1 != 0) && (index2 != 0) && (abs(index1 - index2) < 50))
Laser_Line.at<uint8_t>(i, (index1 + index2) / 2) = 255;
index1 = 0;
index2 = 0;
}
imshow("阈值法", Laser_Line);
waitKey(0);
return Laser_Line;
}
灰度质心法:
将图像转为灰度图并二值化,把灰度值看作质量,每一行的重心作为激光线的中心
Mat Gray_Weighted(Mat Src)
{
Mat img = Src.clone();
Mat Laser_Line(Src.rows, Src.cols, CV_8UC1);
int threshod = 150;
int h = img.rows, w = img.cols;
cvtColor(img, img, CV_BGR2GRAY);
medianBlur(img, img, 3);
threshold(img, img, threshod, 255, 0);
for (int i = 0; i < img.rows; i++)
{
long long sxp = 0, sp = 0, xpos;
for (int j = 0; j < img.cols; j++)
{
sxp += (j*(long long)(img.at<uint8_t>(i, j)));
sp += (long long)(img.at<uint8_t>(i, j));
}
if (sp)
{
xpos = sxp / sp;//xpos即为每一行的重心坐标
//xpos就是这一行的重心纵坐标
Laser_Line.at<uint8_t>(i, xpos) = 255;
}
}
imshow("灰度质心法", Laser_Line);
waitKey(0);
return Laser_Line;
}