cv::RotatedRect和cv::getRotationMatrix2D
在box逆时针旋转过程,与x正轴相交的第一条边就是w,另外是h,w和h的大小没有必然联系。以下opencv的版本为4.0.6,尤其以前的老版本有很大差异。3、按照最小角度旋转,下面是伪代码,注意就是angle的问题。1、cv::RotatedRect返回的w,h,angle。angle返回值是[0,90],为图示所讲的角度。// angle>0时,绕逆时针旋转。
·
以下opencv的版本为4.0.6,尤其以前的老版本有很大差异。
1、cv::RotatedRect返回的w,h,angle

在box逆时针旋转过程,与x正轴相交的第一条边就是w,另外是h,w和h的大小没有必然联系。
angle返回值是[0,90],为图示所讲的角度。
2、cv::getRotationMatrix2D
cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, 1.0);
// angle>0时,绕逆时针旋转
3、按照最小角度旋转,下面是伪代码,注意就是angle的问题
// 计算最小外接矩形
// opencv的版本是4.0.6
// 原点在图像(0,0)位置,水平向左为x正,竖直向下为y正
cv::RotatedRect rotatedRect = cv::minAreaRect(contours[maxAreaIdx]);
// 将检测到的矩形坐标映射回原图尺寸
float scaleX = static_cast<float>(originalImage.cols) / oW;
float scaleY = static_cast<float>(originalImage.rows) / oH;
// 缩放矩形坐标到原图尺寸
cv::Point2f center = rotatedRect.center;
center.x *= scaleX;
center.y *= scaleY;
cv::Size2f size = rotatedRect.size;
size.width *= scaleX;
size.height *= scaleY;
float angle = rotatedRect.angle; //输出在[0,90]
//按照最小角度进行旋转
if(angle>45) {
angle=angle-90;
std::swap(size.width, size.height);
}
// 创建变换矩阵以校正旋转矩形到水平方向
// angle>0时,绕逆时针旋转
cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, 1.0);
// 执行旋转校正
cv::Mat rotatedImage;
cv::warpAffine(originalImage, rotatedImage, rotationMatrix,
cv::Size(originalImage.cols, originalImage.rows),
cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
// 根据角度确定宽高
cv::Size rectSize=cv::Size(static_cast<int>(size.width), static_cast<int>(size.height));
// 计算旋转后的边界框
cv::Rect bbox = cv::RotatedRect(center, size, angle).boundingRect();
// 确保边界框在原图范围内
bbox &= cv::Rect(0, 0, originalImage.cols, originalImage.rows);
// 截取校正后的矩形区域
cv::Rect roiRect(center.x - size.width/2, center.y - size.height/2,
static_cast<int>(size.width), static_cast<int>(size.height));
// 正确调整ROI区域,确保不超出图像边界
if (roiRect.x < 0) {
roiRect.width += roiRect.x; // 减少宽度
roiRect.x = 0;
}
if (roiRect.y < 0) {
roiRect.height += roiRect.y; // 减少高度
roiRect.y = 0;
}
if (roiRect.x + roiRect.width > rotatedImage.cols) {
roiRect.width = rotatedImage.cols - roiRect.x;
}
if (roiRect.y + roiRect.height > rotatedImage.rows) {
roiRect.height = rotatedImage.rows - roiRect.y;
}
auto postprocess_time = 1000.0 * (clock() - begin_time) / CLOCKS_PER_SEC;
printf("postprocess: %.1fms\n",postprocess_time);
if (roiRect.width > 0 && roiRect.height > 0) {
output = rotatedImage(roiRect).clone();
return true;
} else {
// 如果截取失败,返回分割图
output = pred;
return false;
}
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)