opencv版本:opencv3.4.1

目录

1. 图像翻转(坐标映射)

2.  平移

3. 缩放

4. 旋转


1. 图像翻转(坐标映射)

int main()
{cv::Mat srcImage = cv::imread("./lena.jpg");if(!srcImage.data){return -1;}int rows = srcImage.rows;int cols = srcImage.cols;  //输出矩阵定义cv::Mat resultImage(rows, cols, srcImage.type());//x与y方向的矩阵cv::Mat xMapImage(rows, cols, CV_32FC1);cv::Mat yMapImage(rows, cols, CV_32FC1);//图像遍历for(int r = 0; r < rows; r++){for(int c = 0; c < cols; c++){//x与y均翻转xMapImage.at<float>(r,c) = cols-c;yMapImage.at<float>(r,c) = rows-r;}}remap(srcImage, resultImage, xMapImage, yMapImage, CV_INTER_LINEAR,   cv::BORDER_CONSTANT,Scalar(0,0,0));cv::imwrite("resultImage.jpg", resultImage);
}

效果:

2.  平移

有两种情况,(a)平移时图像大小保持不变; (b)平移时图像大小变化;

//平移不改变图像
//参数:平移的图像,平移的x和y偏移量;
cv::Mat imageTranslateNoChange(cv::Mat &srcImage, int xOffset, int yOffset)
{int nRows = srcImage.rows;int nCols = srcImage.cols;cv::Mat resultImage(nRows, nCols, srcImage.type());//遍历图像for(int r = 0 ; r < nRows; r++){for(int c = 0; c < nCols; c++){int x = c - xOffset;int y = r - yOffset;//边界判断;if(x >= 0 && y >= 0 && x < nCols && y < nRows){resultImage.at<cv::Vec3b>(r, c) = srcImage.ptr<cv::Vec3b>(y)[x];}}}return resultImage;
}//平移,会改变图像
cv::Mat imageTranslateChange(cv::Mat &srcImage, int xOffset, int yOffset)
{int nRows = srcImage.rows + abs(yOffset);//加上yint nCols = srcImage.cols + abs(xOffset);//加上xcv::Mat resultImage(nRows, nCols, srcImage.type());//遍历图像for(int r = 0 ; r < nRows; r++){for(int c = 0; c < nCols; c++){int x = c - xOffset;int y = r - yOffset;//边界判断;if(x >= 0 && y >= 0 && x < nCols && y < nRows){resultImage.at<cv::Vec3b>(r, c) = srcImage.ptr<cv::Vec3b>(y)[x];}}}return resultImage;
}int main()
{cv::Mat srcImage = cv::imread("./lena.jpg");if(!srcImage.data){return -1;}//cv::Mat resultImage = imageTranslateNoChange(srcImage, 200, 50);//cv::imwrite("translateNoChange.jpg", resultImage);cv::Mat resultImage = imageTranslateChange(srcImage, 80, 80);cv::imwrite("translateChange.jpg", resultImage);return  0;
}

效果:

3. 缩放

//等间隔提取图像缩放
cv::Mat imageEquidistant(cv::Mat& srcImage, float kx, float ky)
{//获取输出图像分辨率int nRows = cvRound(srcImage.rows * kx);int nCols = cvRound(srcImage.cols * ky);cv::Mat resultImage(nRows, nCols, srcImage.type());for(int i = 0; i < nRows; ++i){for(int j = 0; j < nCols; ++j){//根据水平因子计算坐标int x = static_cast<int>((i+1)/kx+0.5)-1;//根据垂直因子计算坐标int y = static_cast<int>((j+1)/ky+0.5)-1;resultImage.at<cv::Vec3b>(i, j) = srcImage.at<cv::Vec3b>(x,y);}}return resultImage;
}static cv::Vec3b areaAverage(cv::Mat& srcImage, Point_<int> leftPoint, Point_<int> rightPoint)
{int temp1 = 0, temp2=0, temp3=0;//计算区域子块像素点个数int nPix = (rightPoint.x - leftPoint.x) * (rightPoint.y - leftPoint.y);//对区域子块各个通道对像素求和for(int i = leftPoint.x; i < rightPoint.x ;++i){for(int j = leftPoint.y; j < rightPoint.y; ++j){temp1 += srcImage.at<cv::Vec3b>(i,j)[0];temp2 += srcImage.at<cv::Vec3b>(i,j)[1];temp3 += srcImage.at<cv::Vec3b>(i,j)[2];}}//对每个通道求均值Vec3b vecTemp;vecTemp[0] = temp1 / nPix;vecTemp[1] = temp2 / nPix;vecTemp[2] = temp3 / nPix;return vecTemp;
}//基于子块提取图像缩放
cv::Mat imageRegionSubBlock(cv::Mat& srcImage, double kx, double ky)
{//获取输出图像分辨率int nRows = cvRound(srcImage.rows * kx);int nCols = cvRound(srcImage.cols * ky);cv::Mat resultImage(nRows, nCols, srcImage.type());//区域子块的左上角行列坐标int leftRowCoordinate = 0;int leftColCoordinate = 0;for(int i = 0; i < nRows; ++i){//根据水平因子计算坐标int x = static_cast<int>((i+1)/kx+0.5)-1;for(int j = 0; j < nCols; ++j){//根据垂直因子计算坐标int y = static_cast<int>((j+1)/ky+0.5)-1;//求解区域子块的均值;resultImage.at<Vec3b>(i, j) = areaAverage(srcImage,Point_<int>(leftRowCoordinate,leftColCoordinate),Point_<int>(x,y));//更新子块左上角的列坐标leftColCoordinate = y + 1;}leftColCoordinate = 0;//更新子块左上角的行坐标leftRowCoordinate = x + 1;}return resultImage;
}
int main()
{cv::Mat srcImage = cv::imread("./lena.jpg");if(!srcImage.data){return -1;}cv::Mat resultImage;//resultImage = imageEquidistant(srcImage, 0.5, 0.5);resultImage = imageRegionSubBlock(srcImage, 0.5, 0.5);cv::imwrite("RegionSubBlock.jpg", resultImage);return  0;
}

效果:

4. 旋转

cv::Mat imageRotate(cv::Mat& srcImage, int angle)
{//角度转换float alpha = angle * CV_PI / 180;//构造旋转矩阵float rotateMat[3][3] = {{cos(alpha), -sin(alpha), 0},{sin(alpha), cos(alpha), 0},{0 , 0, 1}};int nSrcRows = srcImage.rows;int nSrcCols = srcImage.cols;//计算旋转后图像矩阵的各个顶点位置float a1 = nSrcCols * rotateMat[0][0] ;float b1 = nSrcCols * rotateMat[1][0] ;float a2 = nSrcCols * rotateMat[0][0] + nSrcRows * rotateMat[0][1];float b2 = nSrcCols * rotateMat[1][0] + nSrcRows * rotateMat[1][1];;float a3 = nSrcRows * rotateMat[0][1] ;float b3 = nSrcRows * rotateMat[1][1] ;int kxMin = min(min(min(0.0f,a1),a2),a3);int kxMax = max(max(max(0.0f,a1),a2),a3);int kyMin = min(min(min(0.0f,b1),b2),b3);int kyMax = max(max(max(0.0f,b1),b2),b3);//计算输出矩阵的尺寸int nRows = abs(kxMax - kxMin);int nCols = abs(kyMax - kyMin);cv::Mat dst(nRows, nCols, srcImage.type(), cv::Scalar::all(0));for(int i = 0; i < nRows; ++i){for(int j = 0 ; j < nCols; ++j){//旋转坐标转换int x = (j + kxMin) * rotateMat[0][0] - (i + kyMin) * rotateMat[0][1];int y = -(j + kxMin) * rotateMat[1][0] + (i + kyMin) * rotateMat[1][1];//区域旋转if((x >= 0) && (x < nSrcCols) && (y >= 0) && y < nSrcRows){dst.at<cv::Vec3b>(i, j) = srcImage.at<cv::Vec3b>(y,x);}}}return dst;
}

4.1 旋转30和60度;

int main()
{cv::Mat srcImage = cv::imread("./lena.jpg");if(!srcImage.data){return -1;}cv::Mat resultImage;//resultImage = imageRotate(srcImage,30);resultImage = imageRotate(srcImage,60);cv::imwrite("rotate60.jpg", resultImage);return  0;
}

效果:

图像翻转是图像旋转的特例,opencv中提供了traspose与filp函数对图像进行矩阵转置变换;可以将图像进行水平或垂直翻转;

4.2 图像翻转

int main()
{cv::Mat srcImage = cv::imread("./lena.jpg");if(!srcImage.data){return -1;}cv::Mat resultImage;//transpose(srcImage, resultImage);//逆时针旋转90;//flip( srcImage, resultImage, 0); //垂直翻转//flip( srcImage, resultImage, 1); //水平翻转//flip( srcImage, resultImage, -1);//垂直和水平翻转cv::imwrite("flip-1.jpg", resultImage);return  0;
}

效果:

5. 仿射变换

int main()
{cv::Mat srcImage = cv::imread("./lena.jpg");if(!srcImage.data){return -1;}int nRows = srcImage.rows;int nCols = srcImage.cols;//定义仿射变换的二维点数组//源图像和目标图像对应映射的三个点cv::Point2f srcPoint[3];cv::Point2f resPoint[3];srcPoint[0] = cv::Point2f(0, 0);srcPoint[1] = cv::Point2f(nCols-1, 0);srcPoint[2] = cv::Point2f(0,nRows-1);resPoint[0] =cv::Point2f(nCols*0, nRows*0.33);resPoint[1] =cv::Point2f(nCols*0.85, nRows*0.25);resPoint[2] =cv::Point2f(nCols*0.15, nRows*0.7);//定义仿射变换矩阵cv::Mat warpMat(cv::Size(2,3), CV_32F);cv::Mat resultImage;cv::Mat::zeros(nRows, nCols, srcImage.type());//计算仿射变换矩阵,即仿射变换的2x3数组warpMat = cv::getAffineTransform(srcPoint, resPoint);//根据仿射矩阵计算图像仿射变换cv::warpAffine(srcImage, resultImage, warpMat, cv::Size(resultImage.rows,resultImage.cols));cv::imwrite("warpAffine.jpg", resultImage);#if 1//设置仿射变换参数cv::Point2f centerPoint = cv::Point2f(nCols/2, nRows/2);double angle = -50;double scale = 0.7;//获取仿射变换矩阵warpMat = getRotationMatrix2D(centerPoint, angle, scale);//对源图像进行角度仿射变换cv::warpAffine(srcImage, resultImage, warpMat, cv::Size(resultImage.rows,resultImage.cols));#endif cv::imwrite("warpAffine-angle.jpg", resultImage);return  0;
}

效果:

opencv之图像翻转、平移、缩放、旋转、仿射学习笔记相关推荐

  1. [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. Matlab图像的平移,旋转,缩放,裁剪

    %%------------------------Matlab图像的平移,旋转,缩放,裁剪------------------------------- %-------------------头文 ...

  3. 计算机视觉开源库OpenCV之图像翻转

    计算机视觉开源库OpenCV之图像翻转,包括水平翻转.上下翻转.水平翻转后上下翻转等,函数为为cv2.flip(). 效果如下: 示例代码如下: #!/usr/bin/env python3 impo ...

  4. OpenCV实现图像翻转

    OpenCV实现图像翻转 2010-09-13 19:49 今天在实时处理图像采集卡采集的图像时,发现直接将图像采集卡采集的图像cvShowImage出来的是反着的图像,也就是图像采集卡采集的图像是以 ...

  5. qgraphicsview鼠标移动图片_交互式QGraphicsView(平移/缩放/旋转)-阿里云开发者社区...

    简述 Graphics View提供了一个平台用于大量自定义 2D 图元的管理与交互框架包括一个事件传播架构支持场景 Scene 中的图元 Item 进行精确的双精度交互功能.Item 可以处理键盘事 ...

  6. 基于opencv的图像等比例缩放

    项目中图片经常需要resize,但是直接调用resize方法可能会使图像造成畸变,下面给出,基于opencv的图像等比例缩放的方法. import cv2def resize_keep_aspectr ...

  7. 基于opencv库对图像进行平移,旋转以及翻转

    1.平移: 在opencv中,通过warpAffine函数实现图像平移,格式为: # cv2.warpAffine(src,M,dsize[,dst[,flags[,borderMode[,borde ...

  8. android旋转缩放布局,Android学习笔记(一):双指缩放及旋转计算

    请尊重原创,转载请注明来源. Android中,很多时候会用到手势判断,判断用户当前的手势是移动,还是双指缩放/旋转,关于Android中的手势和gesturedetector,已经有很多人进行过研究 ...

  9. “文化遗产图像智能应用——让图像价值看得见”讲座学习笔记

    教授围绕如何让图像成为活的资源,如何深度挖掘图像的价值展开了一次题为"文化遗产图像智能应用--让图像价值看得见"的讲座,结合团队的研项目成果"多维度图像智慧系统" ...

最新文章

  1. android视频聊天桌面小窗口怎么实现,android视频通话悬浮窗的适配
  2. Callable的简单使用
  3. Jenkins安装与启动
  4. wxWidgets:wxDataObjectComposite类用法
  5. 找出SAP OData service出错根源的小技巧
  6. C#中结构体定义并转换字节数组
  7. 虚拟机体验苹果系统.Mac OS X On VMware.[Intel/AMD]版本
  8. javascript 用函数语句和表达式定义函数的区别详解
  9. Python版猜数游戏
  10. shell命令xargs
  11. 程序结构程序设计(四)
  12. 华为 HG255D 刷openwrt trunk 支持ipv6
  13. 如何看懂一个c语言项目,初学者怎样看懂代码 学习代码编程的注意事项
  14. 微信小程序订阅服务器,微信小程序之模板订阅消息
  15. 辛格函数sinc(x)和抽样函数Sa(t)
  16. Win10 Microsoft Store无法安装程序解决方法
  17. 怎样抠图怎么把背景换成白色?几个步骤教你轻松掌握
  18. 有意思的hand-crafted features based IQA的论文吧2(图像质量评价)
  19. Intouch学习笔记一
  20. 建议收藏 | 数据化、信息化、数字化、智能化到底都是指什么?彼此有什么联系?

热门文章

  1. 推荐一个动画框架Lottie
  2. Linux 4.15亮点特性
  3. 从一线城市回家工作的体验
  4. 预防WinRAR文件损坏
  5. uniapp实现生成海报功能
  6. 鸿蒙系统基于Linux打造,其本质还是安卓系统?
  7. 中止执行后超过2年_超过两年是否可以申请强制执行
  8. 罗德里格斯公式(Rodrigues‘ rotation formula)推导
  9. NBUT1225-NEW RDSP MODE I
  10. python 桑基图 地理坐标_利用Python+Excel制作桑基(Sankey)图