从 360 度仪表读取角度
Read angle from a 360 degre meter
我有一个使用 openCV 成功提取的仪表
Image of the meter in different positions中间白色的东西是一个指针,可以从0到360。
我的代码:
void readAngleOfMeter(Mat image, int number)
{
cvtColor(image, image, COLOR_BGR2GRAY);
inRange(image, Scalar(255, 255, 255), Scalar(255, 255, 255), image);
vector<Vec2f> lines;
HoughLines(tmp, lines, 1, CV_PI / 360, 30, 0, 0);
if (lines.size() == 0) {
cout << "No lines found" << endl;
return;
}
float thetasum = 0;
for (size_t i = 0; i < lines.size(); i++)
{
float theta = lines[i][1];
thetasum += theta;
}
thetasum = thetasum / static_cast<int>(lines.size());
cout << "Theta " << thetasum << endl;
}
我现在的问题是我想读取仪表的角度。所以我考虑过使用每条线的平均角度,但问题是它不起作用,因为一条线可以用两种方式解释(示例 90 与 270 相同)以及当它从 360 变为 0 时。
有什么想法吗?
您甚至不需要使用霍夫变换。编写一个循环,以 1 度为增量从 0 度迭代到 360 度,查看以图像中心为中心的圆中的像素。记住第一个白色像素的角度,当你找到下一个围绕圆圈的黑色像素时,取它的角度并与起始角度平均。
您可能需要先模糊一点或扩大仪表针以填补任何空白。
试验半径 - 较小的半径会使您的分辨率降低,因为那里的针看起来更粗。较大的半径将为您提供更高的分辨率,但您可能会错过针头,因为它离中心更细。
霍夫函数确实会留下不可恢复的180°不确定性
您可以计算交点,即估计中心点并检查它位于 ROI 的哪一侧(如有必要,沿平分线采样以找到指针的方向。
已解决,这是我使用的代码。
float radius = 50;
bool found = false;
float startv = 0;
float endv = 0;
for (float v = 0; v < 360; v++)
{
int x = center.x + cos(v * CV_PI / 180.0) * radius;
int y = center.y + sin(v * CV_PI / 180.0) * radius;
Point p{x,y};
if (!found && gray.at<uchar>(x, y) != 255) {
startv = v;
found = true;
}
if (found && gray.at<uchar>(x, y) == 255) {
endv = v;
break;
}
}
我有一个使用 openCV 成功提取的仪表 Image of the meter in different positions中间白色的东西是一个指针,可以从0到360。
我的代码:
void readAngleOfMeter(Mat image, int number)
{
cvtColor(image, image, COLOR_BGR2GRAY);
inRange(image, Scalar(255, 255, 255), Scalar(255, 255, 255), image);
vector<Vec2f> lines;
HoughLines(tmp, lines, 1, CV_PI / 360, 30, 0, 0);
if (lines.size() == 0) {
cout << "No lines found" << endl;
return;
}
float thetasum = 0;
for (size_t i = 0; i < lines.size(); i++)
{
float theta = lines[i][1];
thetasum += theta;
}
thetasum = thetasum / static_cast<int>(lines.size());
cout << "Theta " << thetasum << endl;
}
我现在的问题是我想读取仪表的角度。所以我考虑过使用每条线的平均角度,但问题是它不起作用,因为一条线可以用两种方式解释(示例 90 与 270 相同)以及当它从 360 变为 0 时。
有什么想法吗?
您甚至不需要使用霍夫变换。编写一个循环,以 1 度为增量从 0 度迭代到 360 度,查看以图像中心为中心的圆中的像素。记住第一个白色像素的角度,当你找到下一个围绕圆圈的黑色像素时,取它的角度并与起始角度平均。
您可能需要先模糊一点或扩大仪表针以填补任何空白。
试验半径 - 较小的半径会使您的分辨率降低,因为那里的针看起来更粗。较大的半径将为您提供更高的分辨率,但您可能会错过针头,因为它离中心更细。
霍夫函数确实会留下不可恢复的180°不确定性
您可以计算交点,即估计中心点并检查它位于 ROI 的哪一侧(如有必要,沿平分线采样以找到指针的方向。
已解决,这是我使用的代码。
float radius = 50;
bool found = false;
float startv = 0;
float endv = 0;
for (float v = 0; v < 360; v++)
{
int x = center.x + cos(v * CV_PI / 180.0) * radius;
int y = center.y + sin(v * CV_PI / 180.0) * radius;
Point p{x,y};
if (!found && gray.at<uchar>(x, y) != 255) {
startv = v;
found = true;
}
if (found && gray.at<uchar>(x, y) == 255) {
endv = v;
break;
}
}