1.不包含角度的矩形区域提取
opencv提供了一个简单的提取+剪切矩形区域的函数,就是cv::image(cv::rect rect),但是需要注意,cv::rect类并不含有角度信息。
cv::Mat outimage = cvimage(rect);
2. 旋转矩形区域提取
对于旋转矩形cv::RotateRect类,它含有一个旋转角度信息:angle
此时我们可以把提取区域拆分成两步:
1)把原图像绕着矩形中心,旋转angle角度以和提取区域平行,此时就相当于把原图形和矩形的坐标系改为新坐标系CoordinateSystem(Point(0,0), angle=rect.angle, scale=1)
原图像 转正图像
2)创建一个水平矩形rect_1,矩形中心点就是之前旋转矩形的中心点,同时长宽与它相等。把旋转图像的rect_1区域提取出来,就是我们想要的旋转矩形区域。
提取正交矩形区域
不废话直接上代码:
cv::Point2d center = cv::Point2d(rect.center.X, rect.center.Y);//计算图像旋转中心
cv::Mat RotateMat = cv::getRotationMatrix2D(center, angle, 1);//计算旋转矩阵
cv::Mat rotateimage;
cv::warpAffine(cvimage, rotateimage, RotateMat, cvimage.size(), cv::WARP_INVERSE_MAP | cv::INTER_LINEAR);//把矩形和原图像一起旋转
cv::Rect rectangle = cv::Rect((int)(rect.center.x-rect.size.width/2), (int)(rect.center.Y-rect.size.height/2), rect.size.width, rect.size.height);//创建正交矩形
cv::Mat outimage = rotateimage(rectangle);//提取区域
注意代码中rotaterect的center是中心,而正交矩形的原点Origin是左上角
3.使用mask掩膜提取区域
有时候我们需要提取多边形区域,但是不需要把图像剪切出来,此时使用mask进行处理即可
cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1);
cv::fillConvexPoly(mask, box, Scalar(255));
cv::Mat cropimage;
cv::bitwise_and(image,image,cropimage,mask);//在mask区域内对image进行与运算
效果:
此时可以看到,图像尺寸没变,但是区域之外的像素均为无效点