c++提取矩形区域图像的梯度并拟合直线
c++提取旋转矩形区域的边缘最强梯度点,并拟合直线
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main() {
// 加载图像
Mat img = imread("image.jpg", IMREAD_GRAYSCALE);
if (img.empty()) {
cout << "Could not open or find the image!" << endl;
return -1;
}
// 定义旋转矩形 (中心点, 大小, 旋转角度)
Point2f center(img.cols / 2.0f, img.rows / 2.0f);
Size2f size(200, 100); // 矩形大小
float angle = 45; // 旋转角度
RotatedRect rotatedRect(center, size, angle);
// 提取旋转矩形区域
Mat rotatedRegion;
Mat rotationMatrix = getRotationMatrix2D(center, angle, 1.0);
warpAffine(img, rotatedRegion, rotationMatrix, img.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0));
Rect boundingRect = rotatedRect.boundingRect();
Mat croppedRegion = rotatedRegion(boundingRect);
// 计算梯度
Mat gradX, gradY, gradMag, gradDir;
Sobel(croppedRegion, gradX, CV_32F, 1, 0); // X方向梯度
Sobel(croppedRegion, gradY, CV_32F, 0, 1); // Y方向梯度
magnitude(gradX, gradY, gradMag); // 梯度幅值
phase(gradX, gradY, gradDir, true); // 梯度方向
// 找到最强梯度点
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(gradMag, &minVal, &maxVal, &minLoc, &maxLoc);
// 提取梯度最强的点
vector<Point2f> strongGradientPoints;
float threshold = 0.8 * maxVal; // 设置阈值
for (int y = 0; y < gradMag.rows; y++) {
for (int x = 0; x < gradMag.cols; x++) {
if (gradMag.at<float>(y, x) > threshold) {
strongGradientPoints.push_back(Point2f(x + boundingRect.x, y + boundingRect.y));
}
}
}
// 拟合直线
Vec4f lineParams;
fitLine(strongGradientPoints, lineParams, DIST_L2, 0, 0.01, 0.01);
// 计算直线的两个端点
Point2f linePoint(lineParams[2], lineParams[3]);
Point2f lineDirection(lineParams[0], lineParams[1]);
Point2f pt1 = linePoint - lineDirection * 1000; // 延长线
Point2f pt2 = linePoint + lineDirection * 1000;
// 在原图上绘制旋转矩形和拟合的直线
Mat imgDisplay;
cvtColor(img, imgDisplay, COLOR_GRAY2BGR);
Point2f vertices[4];
rotatedRect.points(vertices);
for (int i = 0; i < 4; i++) {
line(imgDisplay, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2);
}
line(imgDisplay, pt1, pt2, Scalar(0, 0, 255), 2);
// 显示结果
imshow("Rotated Region", croppedRegion);
imshow("Gradient Magnitude", gradMag);
imshow("Result", imgDisplay);
waitKey(0);
return 0;
}
效果演示