1、pca 找到图像某个区域的垂直线,并画出来
// 1、 斑块的框+ 血管二值化图,pca 找到垂直血管壁的直线, 还是根据斑块找主轴方向吧
// Step 1: 提取斑块左右范围内的血管像素点坐标,
std::vector<cv::Point> points;
for (int y = 0; y < binaryVessel.rows; y++) {
for (int x = x1; x <= x2; x++) {
if (binaryVessel.at<uchar>(y, x) == 255) {
points.push_back(cv::Point(x, y));
}
}
}
if (points.empty()) {
std::cout << "====================>error No valid pixels in the specified range. 斑块附近的血管分割区域不存在,结束函数功能 " << std::endl;
return;
}
// 转换为 cv::Mat 格式
cv::Mat pointsMat(points.size(), 2, CV_32F);
for (int i = 0; i < points.size(); i++) {
pointsMat.at<float>(i, 0) = points[i].x;
pointsMat.at<float>(i, 1) = points[i].y;
}
// Step 2: 使用 PCA 获取垂直线段斜率,感觉有点异常,不要了,改成用最小外接矩形
// binaryPlaque pointsMat
cv::PCA pca(pointsMat, cv::noArray(), cv::PCA::DATA_AS_ROW);
// Step 3: 获取主成分(直线的方向)和主成分对应的直线上的点
cv::Mat directions = pca.eigenvectors;
cv::Mat linePoints = pca.mean;
// Step 4: 计算垂直线的斜率和截距
float kVertical = -directions.at<float>(0,0) / directions.at<float>(0,1);
float interceptHorizontal = linePoints.at<float>(0, 1) - kVertical * linePoints.at<float>(0, 0);
// Step 5: 绘制垂直线
float x;
cv::Mat image22; // 存储处理后的图像
cv::cvtColor(binaryVessel, image22, cv::COLOR_GRAY2BGR); // binaryVessel 转换为彩色图像 image22,存储
for (int i = 0; i < image22.cols; i++) {
x = static_cast<float>(i);
float yVertical = kVertical * x + interceptHorizontal;
cv::circle(image22, cv::Point(static_cast<int>(x), static_cast<int>(yVertical)), 1, cv::Scalar(0, 255, 0), -1);
}
cv::imwrite("/home/hebin/Desktop/shiyuanyin/image2.png", image22); // 保存画图的直线
2、使用最小外接矩形的框,来找到水平线和垂直线