题目:机器人视觉全自动测量要求:根据待测刹车盘零件上线纹尺的刻度单位:毫米标定出成像测量系统的像素当量值。然后编写OpenCV程序测量:1刹车盘零件上7个小孔的直径;2各相邻孔之间的距离;3外围6个小孔中心所在圆周的直径。请输出基于opencv47的程序实例运用c++语言实现
由于没有待测刹车盘零件的实际图像,我们无法编写完整的程序。因此,下面提供一个基本的程序框架,您需要根据实际情况进行修改和完善。
首先,我们需要标定成像测量系统的像素当量值。这可以通过拍摄一个已知尺寸的标准物体(例如标准尺子)的图像来实现。假设我们已经得到了像素当量值为1像素=0.1毫米。
接下来,我们需要加载待测图像并进行预处理。预处理的具体步骤包括:灰度化、二值化、去除噪声等。这里我们可以使用OpenCV提供的函数来实现:
cv::Mat src = cv::imread("待测图像路径");
cv::Mat gray, binary;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::morphologyEx(binary, binary, cv::MORPH_OPEN, cv::Mat(), cv::Point(-1, -1), 2);
接下来,我们需要找到待测零件上的小孔。这可以通过霍夫变换来实现。找到小孔后,我们可以计算其直径和中心坐标。这里我们以找到一个小孔为例:
std::vector<cv::Vec3f> circles;
cv::HoughCircles(binary, circles, cv::HOUGH_GRADIENT, 1, 50, 100, 30, 10, 20);
if (circles.size() > 0) {
cv::Point center(cvRound(circles[0][0]), cvRound(circles[0][1]));
int radius = cvRound(circles[0][2]);
double diameter = radius * 2 * 0.1; // 像素直径转换为毫米
cv::circle(src, center, radius, cv::Scalar(0, 0, 255), 2);
}
接下来,我们需要计算各相邻孔之间的距离。这可以通过计算两个小孔之间的中心坐标距离来实现。这里以计算第一个和第二个小孔之间的距离为例:
if (circles.size() > 1) {
cv::Point center1(cvRound(circles[0][0]), cvRound(circles[0][1]));
cv::Point center2(cvRound(circles[1][0]), cvRound(circles[1][1]));
double distance = cv::norm(center1 - center2) * 0.1; // 像素距离转换为毫米
cv::line(src, center1, center2, cv::Scalar(0, 0, 255), 2);
}
最后,我们需要计算外围6个小孔中心所在圆周的直径。这可以通过找到6个小孔的中心坐标,然后计算最小外接圆来实现。这里以找到前6个小孔为例:
if (circles.size() >= 6) {
std::vector<cv::Point2f> centers;
for (int i = 0; i < 6; i++) {
cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
centers.push_back(center);
}
cv::Point2f center;
float radius;
cv::minEnclosingCircle(centers, center, radius);
double diameter = radius * 2 * 0.1; // 像素直径转换为毫米
cv::circle(src, center, cvRound(radius), cv::Scalar(0, 0, 255), 2);
}
完整的程序框架如下:
#include <opencv2/opencv.hpp>
int main() {
// 标定像素当量值
double pixel_ratio = 0.1;
// 加载待测图像并进行预处理
cv::Mat src = cv::imread("待测图像路径");
cv::Mat gray, binary;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::morphologyEx(binary, binary, cv::MORPH_OPEN, cv::Mat(), cv::Point(-1, -1), 2);
// 找到小孔并计算直径和中心坐标
std::vector<cv::Vec3f> circles;
cv::HoughCircles(binary, circles, cv::HOUGH_GRADIENT, 1, 50, 100, 30, 10, 20);
if (circles.size() > 0) {
cv::Point center(cvRound(circles[0][0]), cvRound(circles[0][1]));
int radius = cvRound(circles[0][2]);
double diameter = radius * 2 * pixel_ratio; // 像素直径转换为毫米
cv::circle(src, center, radius, cv::Scalar(0, 0, 255), 2);
}
// 计算相邻孔之间的距离
if (circles.size() > 1) {
cv::Point center1(cvRound(circles[0][0]), cvRound(circles[0][1]));
cv::Point center2(cvRound(circles[1][0]), cvRound(circles[1][1]));
double distance = cv::norm(center1 - center2) * pixel_ratio; // 像素距离转换为毫米
cv::line(src, center1, center2, cv::Scalar(0, 0, 255), 2);
}
// 计算外围6个小孔中心所在圆周的直径
if (circles.size() >= 6) {
std::vector<cv::Point2f> centers;
for (int i = 0; i < 6; i++) {
cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
centers.push_back(center);
}
cv::Point2f center;
float radius;
cv::minEnclosingCircle(centers, center, radius);
double diameter = radius * 2 * pixel_ratio; // 像素直径转换为毫米
cv::circle(src, center, cvRound(radius), cv::Scalar(0, 0, 255), 2);
}
// 显示结果
cv::imshow("result", src);
cv::waitKey(0);
return 0;
}
原文地址: https://www.cveoy.top/t/topic/bKSE 著作权归作者所有。请勿转载和采集!