Opencv如何任意选取的不规则四边形图像变换为矩形图像

hy3268663 2017-04-15 11:18:23


如上图所示:如何将在任意选取的不规则四边形图像变换为矩形图像, 矫正后的矩形图像是会发生曲面变形的。求大神指教,求大侠给出算法。
...全文
2500 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-04-17
  • 打赏
  • 举报
回复
WarpAffine 对图像做仿射变换 void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ); src 输入图像. dst 输出图像. map_matrix 2×3 变换矩阵 flags 插值方法和以下开关选项的组合: CV_WARP_FILL_OUTLIERS - 填充所有输出图像的象素。如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval. CV_WARP_INVERSE_MAP - 指定 map_matrix 是输出图像到输入图像的反变换,因此可以直接用来做象素插值。否则, 函数从 map_matrix 得到反变换。 fillval 用来填充边界外面的值 函数 cvWarpAffine 利用下面指定的矩阵变换输入图像: 如果没有指定 CV_WARP_INVERSE_MAP , , 否则, 函数与 cvGetQuadrangleSubPix 类似,但是不完全相同。 cvWarpAffine 要求输入和输出图像具有同样的数据类型,有更大的资源开销(因此对小图像不太合适)而且输出图像的部分可以保留不变。而 cvGetQuadrangleSubPix 可以精确地从8位图像中提取四边形到浮点数缓存区中,具有比较小的系统开销,而且总是全部改变输出图像的内容。 要变换稀疏矩阵,使用 cxcore 中的函数 cvTransform 。
赵4老师 2017-04-17
  • 打赏
  • 举报
回复
GetQuadrangleSubPix 提取象素四边形,使用子象素精度 void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix ); src 输入图像. dst 提取的四边形. map_matrix 3 × 2 变换矩阵 [A|b] (见讨论). 函数 cvGetQuadrangleSubPix 以子象素精度从图像 src 中提取四边形,使用子象素精度,并且将结果存储于 dst ,计算公式是: dst(x + width(dst) / 2,y + height(dst) / 2) = src(A11x + A12y + b1,A21x + A22y + b2) 其中 A和 b 均来自映射矩阵(译者注:A, b为几何形变参数) ,映射矩阵为: 其中在非整数坐标 的象素点值通过双线性变换得到。当函数需要图像边界外的像素点时,使用重复边界模式(replication border mode)恢复出所需的值。多通道图像的每一个通道都单独计算。 例子:使用 cvGetQuadrangleSubPix 进行图像旋转 #include "cv.h" #include "highgui.h" #include "math.h" int main( int argc, char** argv ) { IplImage* src; /* the first command line parameter must be image file name */ if( argc==2 && (src = cvLoadImage(argv[1], -1))!=0) { IplImage* dst = cvCloneImage( src ); int delta = 1; int angle = 0; cvNamedWindow( "src", 1 ); cvShowImage( "src", src ); for(;;) { float m[6]; double factor = (cos(angle*CV_PI/180.) + 1.1)*3; CvMat M = cvMat( 2, 3, CV_32F, m ); int w = src->width; int h = src->height; m[0] = (float)(factor*cos(-angle*2*CV_PI/180.)); m[1] = (float)(factor*sin(-angle*2*CV_PI/180.)); m[2] = w*0.5f; m[3] = -m[1]; m[4] = m[0]; m[5] = h*0.5f; cvGetQuadrangleSubPix( src, dst, &M, 1, cvScalarAll(0)); cvNamedWindow( "dst", 1 ); cvShowImage( "dst", dst ); if( cvWaitKey(5) == 27 ) break; angle = (angle + delta) % 360; } } return 0; }
Mr_Zhouzl 2017-04-16
  • 打赏
  • 举报
回复
这个只能从硬件去下手,相机不同位置的曲变程度是不一样的,不可能以边缘的变化来代表区域内部的变化,从软件方面基本难以解决。
Mr_Zhouzl 2017-04-16
  • 打赏
  • 举报
回复
这个只能从硬件去下手,相机不同不同的曲变程度是不一样的,不可能以边缘的变化来代表区域内部的变化,从软件方面基本难以解决。
资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在计算机视觉领域,OpenCV 是一个功能强大的开源计算机视觉库,它提供了大量用于处理图像和视频的函数与方法。本教程将介绍如何借助 OpenCV 截取图像中的任意区域,涵盖规则图形(例如圆、椭圆、矩形)以及通过鼠标选取不规则区域。这些操作在图像分析、标注、分割等诸多应用中十分常见,而了解 ROI(Region of Interest,感兴趣区域)的概念至关重要。在图像处理过程中,ROI 指的是图像中我们特别关注或需要进行特定处理的那部分区域,OpenCV 提供了多种方法来定义和操作 ROI,从而便于我们对这些区域开展进一步的分析或操作。 首先,截取矩形区域时,OpenCV 中的 cv2.rectangle() 函数可用于绘制矩形并截取相应区域,该函数需接收四个参数,分别是原始图像矩形左上角坐标、右下角坐标以及矩形的颜色和线宽。比如: 其次,截取圆形区域可借助 cv2.circle() 函数来实现,它要求提供图像、圆心坐标、半径、颜色和线宽等参数。不过需要注意的是,OpenCV 并不能直接截取圆形 ROI,常规做法是先在原图上绘制出圆形,再根据所画圆的边界截取矩形区域,示例如下: 再者,截取椭圆区域与截取圆形区域类似,使用 cv2.ellipse() 函数绘制椭圆,但同样需要利用一个矩形来截取椭圆区域,椭圆的参数包括中心坐标、长轴和短轴长度、旋转角度、颜色和线宽。 最后,对于不规则区域的截取,可以利用 OpenCV 的 cv2.setMouseCallback() 函数来监听鼠标事件。当用户点击并拖动鼠标时,记录起点和终点坐标,进而根据这些点构建一个四边形来截取 ROI,这通常会涉及一些较为复杂的图像处理技术,比如连通组件分析。以下是一个基本的鼠标选择 ROI示 的例代码: 在这个示

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧