-
2021-10-28 20:43:02
MATLAB初学——Matlab实现图像的几何变换
1.图像比例缩放变换
主要函数:imresize()
实现代码image = imread('test.bmp'); image_1 = imresize(image,0.5); %比例缩小0.5倍 image_2 = imresize(image,[320,410]); %非比例缩小(指定行数和列数) image_3 = imresize(image,2); %比例放大1倍 figure(1) imshow(image); title('原图'); figure(2) imshow(image_1); title('比例缩小0.5倍'); figure(3) imshow(image_2); title('非比例缩小'); figure(4) imshow(image_3); title('比例放大');
2.图像平移变换
主要函数:translate(); imdilate(); imtranslate()
实现代码image = imread('test.bmp'); se = translate(strel(1), [150 150]); %将一个平面结构化元素分别向下和向右移动150个位置 image_1 = imdilate(image,se); %利用膨胀函数平移图像 image_2 = imtranslate(image,[150,150],'OutputView','full'); %平移后保持图像完整 figure(1) imshow(image); title('原图'); figure(2) imshow(image_1); title('平移后的图像'); figure(3) imshow(image_2); title('平移后不被截去的图像');
3.图像镜像变换
主要函数:maketform(); imtransform();
实现代码image = imread('test.bmp'); [height,width,dim] = size(image); tform = maketform('affine',[-1 0 0;0 1 0;width 0 1]); image_1 = imtransform(image,tform,'nearest'); tform2 = maketform('affine',[1 0 0;0 -1 0;0 height 1]); image_2 = imtransform(image,tform2,'nearest'); subplot(1,3,1); imshow(image); title('原图像'); subplot(1,3,2); imshow(image_1); title('水平镜像'); subplot(1,3,3); imshow(image_2); title('垂直镜像');
4.图像旋转变换
主要函数:imrotate()
实现代码image = imread('test.bmp'); image_1 = imrotate(image,40,'nearest','crop'); %最近邻插值 image_2 = imrotate(image,40,'nearest','loose'); figure; imshow(image); title('原图像'); figure; imshow(image_1); title('旋转后图像'); figure; imshow(image_2); title('旋转后不被截去图像');
5.图像绕某点(非中心点)旋转
自定义函数,构建变换矩阵,与原图像矩阵相乘,实现先平移后旋转功能
实现代码function rotate(img) [m,n] = size(img); M = ones(m,n); T1 = [1,0,0;0,1,0;-66,-66,1]; %平移至点P(66,66) T2 = [cosd(60),-sind(60),0;sind(60),cosd(60),0;0,0,1]; %逆时针旋转60° T =T2*T1; %变换矩阵 for i=1:m for j=1:n p = floor([i,j,1]*T); if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围 M(i,j) = img(p(1),p(2)); else M(i,j) = 0; end end end figure; imshow(M,[]); title('绕点P逆时针旋转60°'); image = imread('test.bmp'); image_1 = rgb2gray(image); figure subimage(image_1); title('原图'); rotate(image_1)
更多相关内容 -
Python实现图像几何变换
2020-12-25 03:01:21本文实例讲述了Python实现图像几何变换的方法。分享给大家供大家参考。具体实现方法如下: import Image try: im=Image.open('test.jpg') #out = im.resize((128, 128)) #改变大小 #out = im.rotate(45) #45°... -
MATLAB中的图像几何变换
2017-06-26 09:08:14MATLAB中图像基本变换的命令,适用于初学者 -
OpenCV图像几何变换之透视变换
2021-01-01 09:10:52本文实例为大家分享了OpenCV图像几何变换之透视变换的具体代码,供大家参考,具体内容如下 1. 基本原理 透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式为: (u,v... -
matlab数字图像处理之图像几何变换
2018-04-29 18:35:50将图片Colorful Rose贴在抛物面z=x2+y2 ( x ≥0, 100 ≥z ≥10) 上,并显示正视图和俯视图。matlab实现。 -
图像几何变换
2012-12-17 19:41:13关于图像处理的几何变换 mfc源代码 平移 旋转 缩放 镜像 -
单片机与DSP中的图像几何变换的DSP算法研究与实现
2020-11-05 22:49:24其中数字扫描变换的精度直接影响图像的分辨率和几何失真度,变换算法的复杂度直接影响图像处理运算量和图像处理的实时性,也直接影响后续图像处理的质量。 DSP易于满足图像处理中运算量大、精度高、实时性强、... -
数字图像处理图像几何变换
2013-06-26 11:07:14数字图像处理图像的几何变换C++代码实现 -
图像几何变换代码_图像的几何变换_
2021-09-30 10:17:20实现图像几何变换,harris特征点检测 -
数字图像处理实验03——图像几何变换
2022-03-26 00:24:00数字图像处理实验03—图像几何变换 常见的数字图像的几何变换包括平移、镜像、旋转、缩放和错切等,是图像处理软件必须具备的操作手段。本次实验的目的是要求掌握各种变换的基本原理和方法,能够运用Matlab编写程序...数字图像处理实验03
图像几何变换
常见的数字图像的几何变换包括平移、镜像、旋转、缩放和错切等,是图像处理软件必须具备的操作手段。本次实验的目的是要求掌握各种变换的基本原理和方法,能够运用Matlab编写程序,实现这些变换。其中,由于变化产生的空穴、马赛克和锯齿现象,希望能够采用适当的插值算法,消除它们的影响,改善图像质量
图像平移
I=imread('****.jpg'); dltI=20; dltJ=30 [m,n]=size(I); G=uint8(zeros(m,n));%没有扩大画布 for i=1:m for j=1:n if(((i-dltI>0) && (i-dltI<=m)) && ((j-dltJ>0 )&&( j-dltJ<=n))) G(i,j) = I(i-dltI,j-dltJ); end end end Ge=uint8(zeros(m+dltI,n+dltJ));%扩大画布 for i=1:(m+dltI) for j=1:(n+dltJ) if(((i-dltI>0) && (i-dltI<=m)) && ((j-dltJ>0 )&&( j-dltJ<=n))) Ge(i,j) = I(i-dltI,j-dltJ); end end end subplot(1,3,1);imshow(I); title("原图像"); subplot(1,3,2);imshow(G); title("无扩大画布平移图像"); subplot(1,3,3);imshow(Ge); title("扩大画布平移图像");
图像镜像
I=imread('gull.jpg'); [m,n]=size(I); Ih=uint8(zeros(m,n));%水平镜像 for i=1:m for j=1:n Ih(i,m-j+1)=I(i,j); end end Iv=uint8(zeros(m,n));%垂直镜像 for i=1:m for j=1:n Iv(m-i+1,j)=I(i,j); end end subplot(1,3,1);imshow(I); title("原图像"); subplot(1,3,2);imshow(Ih); title("水平镜像图像"); subplot(1,3,3);imshow(Iv); title("垂直镜像图像");
图像旋转
F=imread('gull.jpg'); [m,n]=size(F); I=zeros(m,n);J=zeros(m,n); %坐标矩阵 for i=1:m I(i,:)=i; end for j=1:n J(:,j)=j; end II=I.*cos(pi/6)-J.*sin(pi/6);%逆时针旋转30度 JJ=I.*sin(pi/6)+J.*cos(pi/6); II=int16(II);JJ=int16(JJ); %取整 mini=min(min(II));%计算画布大小 maxi=max(max(II)); II = II+(1-mini); minj=min(min(JJ)); maxj=max(max(JJ)); JJ = JJ+(1-minj); maxII=max(max(II)); maxJJ=max(max(JJ)); G=uint8(zeros(maxII,maxJJ));%生成新图像 for i=1:m for j=1:n G(II(i,j),JJ(i,j)) = F(i,j); end end subplot(1,2,1);imshow(F); subplot(1,2,2);imshow(G);
F=imread('gull.jpg'); [m,n]=size(F); I=zeros(m,n);J=zeros(m,n); %坐标矩阵 for i=1:m I(i,:)=i; end for j=1:n J(:,j)=j; end II=I.*cos(pi/6)-J.*sin(pi/6);%逆时针旋转30度 JJ=I.*sin(pi/6)+J.*cos(pi/6); II=int16(II);JJ=int16(JJ); %取整 %计算画布大小 mini=min(min(II)); maxi=max(max(II)); II = II+(1-mini); minj=min(min(JJ)); maxj=max(max(JJ)); JJ = JJ+(1-minj); maxII=max(max(II)); maxJJ=max(max(JJ)); %生成新图像 G=uint8(zeros(maxII,maxJJ)); for i=1:m for j=1:n G(II(i,j),JJ(i,j)) = F(i,j); end end %用最近邻插值法消除空穴 Gr=G; [gm,gn]=size(Gr); for i=1:gm for j=1:gn gi=(i-(1-mini)); gj=(j-(1-minj)); invi=int16(gi*cos(-pi/6)-gj*sin(-pi/6)); %逆时针旋转30度 invj=int16(gi*sin(-pi/6)+gj*cos(-pi/6)); %判断是否为背景 if(invi>0 && invi<=m && invj>0 && invj<=n) if(Gr(i,j)==0) if(j<n) Gr(i,j)=Gr(i,j+1); else Gr(i,j)=Gr(i,j-1); end end end end end subplot(1,3,1);imshow(F); title("原图像"); subplot(1,3,2);imshow(G); title("逆时针旋转30度"); subplot(1,3,3);imshow(Gr); title("用最近邻插值法消除空穴");
图像缩放
F=imread('gull.jpg'); [mf,nf]=size(F); %按比例缩小 dlt=2; G1=uint8(zeros(int16(mf/dlt),int16(nf/dlt))); [mg1,ng1]=size(G1); for i=1:mg1 for j=1:ng1 fi=int16(dlt*i); fj=int16(dlt*j); if(fi>mf) fi=mf;end if(fj>nf) fj=nf;end G1(i,j)=F(fi,fj); end end figure;imshow(F); figure;imshow(G1); %不按比例缩小 dlti=2; dltj=3; G2=uint8(zeros(int16(mf/dlti),int16(nf/dltj))); [mg2,ng2]=size(G2); for i=1:mg2 for j=1:ng2 fi=int16(dlti*i); fj=int16(dltj*j); if(fi>mf) fi=mf;end if(fj>nf) fj=nf;end G2(i,j)=F(fi,fj); end end figure;imshow(G2);
F=imread('gull.jpg'); [mf,nf]=size(F); dlt=0.5; G1=uint8(zeros(int16(mf/dlt),int16(nf/dlt))); [mg1,ng1]=size(G1); for i=1:mg1 for j=1:ng1 fi=int16(dlt*i); fj=int16(dlt*j); if(fi>mf) fi=mf; end if(fj>nf) fj=nf; end G1(i,j)=F(fi,fj); end end figure;imshow(F); figure;imshow(G1); dlti=5/6; dltj=0.4; G2=uint8(zeros(int16(mf/dlti),int16(nf/dltj))); [mg2,ng2]=size(G2); for i=1:mg2 for j=1:ng2 fi=int16(dlti*i); fj=int16(dltj*j); if(fi<1) fi=1;end if(fj<1) fj=1;end if(fi>mf) fi=mf;end if(fj>nf) fj=nf;end G2(i,j)=F(fi,fj); end end figure;imshow(G2);
clear; F=[1 4 7;2 5 8;3 6 9]; [m,n]=size(F); G=zeros(4,8); for i=1:4 x=i/1.2; fi=int8(floor(x)); for j=1:8 y=j/2.5; fj=int8(floor(y)); if(fi<1 && fj<1) A=double([F(1,1),F(1,1);F(1,1),F(1,1)]);end if(fi<1 && fj>=1 && fj<n) A=double([F(1,fj),F(1,fj+1);F(1,fj),F(1,fj+1)]);end if(fi<1 && fj>=n) A=double([F(1,n),F(1,n);F(1,n),F(1,n)]);end if(fi<m && fi>=1 && fj<1) A=double([F(fi,1),F(fi,1);F(fi+1,1),F(fi+1,1)]);end if(fi<m && fi>=1 && fj>=1 && fj<n) A=double([F(fi,fj),F(fi,fj+1);F(fi+1,fj),F(fi+1,fj+1)]);end if(fi<m && fi>=1 && fj>=n) A=double([F(fi,n),F(fi,n);F(fi+1,n),F(fi+1,n)]);end if(fi>=m && fj<1) A=double([F(m,1),F(m,1);F(m,1),F(m,1)]);end if(fi>=m && fj>=1 && fj<n) A=double([F(m,fj),F(m,fj+1);F(m,fj),F(m,fj+1)]);end if(fi>=m && fj>=n) A=double([F(m,n),F(m,n);F(m,n),F(m,n)]);end fi=double(fi);fj=double(fj); wx=[abs(1-abs(x-fi)),abs(1-abs(1+fi-x))]; wy=[abs(1-abs(y-fj));abs(1-abs(1+fj-y))]; G(i,j)=int8(wx*A*wy); end end
F=imread('gull.jpg'); [mf,nf]=size(F); %不按比例放大 dlti=5/6; dltj=0.4; G=uint8(zeros(int16(mf/dlti),int16(nf/dltj))); [mg,ng]=size(G); for i=1:mg x=i*dlti; fi=floor(x); for j=1:ng y=j*dltj; fj=floor(y); if(fi<1 && fj<1) A=double([F(1,1),F(1,1);F(1,1),F(1,1)]);end if(fi<1 && fj>=1 && fj<nf) A=double([F(1,fj),F(1,fj+1);F(1,fj),F(1,fj+1)]);end if(fi<1 && fj>=nf) A=double([F(1,nf),F(1,nf);F(1,nf),F(1,nf)]);end if(fi<mf && fi>=1 && fj<1) A=double([F(fi,1),F(fi,1);F(fi+1,1),F(fi+1,1)]);end if(fi<mf && fi>=1 && fj>=1 && fj<nf) A=double([F(fi,fj),F(fi,fj+1);F(fi+1,fj),F(fi+1,fj+1)]);end if(fi<mf && fi>=1 && fj>=nf) A=double([F(fi,nf),F(fi,nf);F(fi+1,nf),F(fi+1,nf)]);end if(fi>=mf && fj<1) A=double([F(mf,1),F(mf,1);F(mf,1),F(mf,1)]);end if(fi>=mf && fj>=1 && fj<nf) A=double([F(mf,fj),F(mf,fj+1);F(mf,fj),F(mf,fj+1)]);end if(fi>=mf && fj>=nf) A=double([F(mf,nf),F(m,n);F(mf,nf),F(mf,nf)]);end fi=double(fi);fj=double(fj); wx=[abs(1-abs(x-fi)),abs(1-abs(1+fi-x))]; wy=[abs(1-abs(y-fj));abs(1-abs(1+fj-y))]; G(i,j)=uint8(wx*A*wy); end end figure;imshow(F); figure;imshow(G);
图像错切
clear; F=imread('gull.jpg'); [mf,nf]=size(F); angle = 10*pi/180; %水平错切 Gh=uint8(zeros(int16(mf+nf*tan(angle)),nf)); for i=1:mf for j=1:nf Gh(int16(i+j*tan(angle)),j) = F(i,j); end end %垂直错切 Gv=uint8(zeros(mf,int16(nf+mf*tan(angle)))); for i=1:mf for j=1:nf Gv(i,int16(j+i*tan(angle))) = F(i,j); end end figure;imshow(F); figure;imshow(Gh); figure;imshow(Gv);
代码文件可以从主页发布里面找
万水千山都是情,路过点个赞行不行!
希望看见的都可以帮忙点个赞!拜托了!
觉得还可以的动动手指帮忙点个赞!呜呜~ -
[Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)
2022-01-27 21:32:12欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习...这篇文章将详细讲解图像几何变换,包括图像平移、图像缩放和图像旋转。希望文章对您有所帮助,如果有不足之处,还请海涵。欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望我们都能在人生路上开心快乐、共同成长。
该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。
上一篇文章介绍了图像融合处理和ROI区域绘制,同时补充图像属性、通道和类型转换。这篇文章将详细讲解图像几何变换,包括图像平移、图像缩放和图像旋转。希望文章对您有所帮助,如果有不足之处,还请海涵。
下载地址:
前文赏析:
第一部分 基础语法
- [Python从零到壹] 一.为什么我们要学Python及基础语法详解
- [Python从零到壹] 二.语法基础之条件语句、循环语句和函数
- [Python从零到壹] 三.语法基础之文件操作、CSV文件读写及面向对象
第二部分 网络爬虫
- [Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例
- [Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解
- [Python从零到壹] 六.网络爬虫之BeautifulSoup爬取豆瓣TOP250电影详解
- [Python从零到壹] 七.网络爬虫之Requests爬取豆瓣电影TOP250及CSV存储
- [Python从零到壹] 八.数据库之MySQL基础知识及操作万字详解
- [Python从零到壹] 九.网络爬虫之Selenium基础技术万字详解(定位元素、常用方法、键盘鼠标操作)
- [Python从零到壹] 十.网络爬虫之Selenium爬取在线百科知识万字详解(NLP语料构造必备技能)
第三部分 数据分析和机器学习
- [Python从零到壹] 十一.数据分析之Numpy、Pandas、Matplotlib和Sklearn入门知识万字详解(1)
- [Python从零到壹] 十二.机器学习之回归分析万字总结全网首发(线性回归、多项式回归、逻辑回归)
- [Python从零到壹] 十三.机器学习之聚类分析万字总结全网首发(K-Means、BIRCH、层次聚类、树状聚类)
- [Python从零到壹] 十四.机器学习之分类算法三万字总结全网首发(决策树、KNN、SVM、分类算法对比)
- [Python从零到壹] 十五.文本挖掘之数据预处理、Jieba工具和文本聚类万字详解
- [Python从零到壹] 十六.文本挖掘之词云热点与LDA主题分布分析万字详解
- [Python从零到壹] 十七.可视化分析之Matplotlib、Pandas、Echarts入门万字详解
- [Python从零到壹] 十八.可视化分析之Basemap地图包入门详解
- [Python从零到壹] 十九.可视化分析之热力图和箱图绘制及应用详解
- [Python从零到壹] 二十.可视化分析之Seaborn绘图万字详解
- [Python从零到壹] 二十一.可视化分析之Pyechart绘图万字详解
- [Python从零到壹] 二十二.可视化分析之OpenGL绘图万字详解
- [Python从零到壹] 二十三.十大机器学习算法之决策树分类分析详解(1)
- [Python从零到壹] 二十四.十大机器学习算法之KMeans聚类分析详解(2)
- [Python从零到壹] 二十五.十大机器学习算法之KNN算法及图像分类详解(3)
- [Python从零到壹] 二十六.十大机器学习算法之朴素贝叶斯算法及文本分类详解(4)
- [Python从零到壹] 二十七.十大机器学习算法之线性回归算法分析详解(5)
- [Python从零到壹] 二十八.十大机器学习算法之SVM算法分析详解(6)
- [Python从零到壹] 二十九.十大机器学习算法之随机森林算法分析详解(7)
- [Python从零到壹] 三十.十大机器学习算法之逻辑回归算法及恶意请求检测应用详解(8)
- [Python从零到壹] 三十一.十大机器学习算法之Boosting和AdaBoost应用详解(9)
- [Python从零到壹] 三十二.十大机器学习算法之层次聚类和树状图聚类应用详解(10)
第四部分 Python图像处理基础
- [Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置
- [Python从零到壹] 三十四.OpenCV入门详解——显示读取修改及保存图像
- [Python从零到壹] 三十五.图像处理基础篇之OpenCV绘制各类几何图形
- [Python从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解
- [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制
- [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)
第五部分 Python图像运算和图像增强
第六部分 Python图像识别和图像处理经典案例
第七部分 NLP与文本挖掘
第八部分 人工智能入门知识
第九部分 网络攻防与AI安全
第十部分 知识图谱构建实战
扩展部分 人工智能高级案例
作者新开的“娜璋AI安全之家”将专注于Python和安全技术,主要分享Web渗透、系统安全、人工智能、大数据分析、图像识别、恶意代码检测、CVE复现、威胁情报分析等文章。虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础性文章对你有所帮助,在Python和安全路上与大家一起进步。
一.图像几何变换
图像几何变换不改变图像的像素值,在图像平面上进行像素变换。适当的几何变换可以最大程度地消除由于成像角度、透视关系乃至镜头自身原因所造成的几何失真所产生的负面影响。几何变换常常作为图像处理应用的预处理步骤,是图像归一化的核心工作之一[1]。
一个几何变换需要两部分运算:
- 空间变换:包括平移、缩放、旋转和正平行投影等,需要用它来表示输出图像与输入图像之间的像素映射关系。
- 灰度插值算法:按照这种变换关系进行计算,输出图像的像素可能被映射到输入图像的非整数坐标上[2]。
图像几何变换在变换过程中会建立一种原图像像素与变换后图像像素之间的映射关系,通过这种关系,能够从一方的像素计算出另一方的像素的坐标位置。通常将图像坐标映射到输出的过程称作向前映射,反之,将输出图像映射到输入的过程称作向后映射。向后映射在实践中使用较多,原因是能够避免使用向前映射中出现映射不完全和映射重叠的问题。
图6-1展示了图像放大的示例,右边图中只有(0,0)、(0,2)、(2,0)、(2,2)四个坐标根据映射关系在原图像中找到了相对应的像素,其余的12个坐标没有有效值[3]。
对于数字图像而言,像素的坐标是离散型非负整数,但是在进行变换的过程中有可能产生浮点坐标值。这在图像处理中是一个无效的坐标。为了解决这个问题需要用到插值算法。常见算法如下:
- 最近邻插值
- 双线性插值
- 双立方插值
图像变换是建立在矩阵运算基础上,通过矩阵运算可以很快找到对应关系。在这篇文章中,我们将介绍常见的图像几何变换,包括图形平移、图像缩放、图像旋转、图像镜像、图像仿射、图像透视等。
二.图像平移
图像平移是将图像中的所有像素点按照给定的平移量进行水平或垂直方向上的移动。假设原始像素的位置坐标为(x0,y0),经过平移量(△x,△y)后,坐标变为(x1, y1),如图6-2所示[3-5]。
用数学式子表示为公式(6-1)。
用矩阵表示如公式(6-2)所示:
式子中,矩阵称为平移变换矩阵或因子,△x和△y称为平移量。图像平移首先定义平移矩阵M,再调用warpAffine()函数实现平移,核心函数如下:
- M = np.float32([[1, 0, x], [0, 1, y]])
– M表示平移矩阵,其中x表示水平平移量,y表示垂直平移量 - shifted = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
– src表示原始图像
– M表示平移矩阵
– dsize表示变换后的输出图像的尺寸大小
– dst为输出图像,其大小为dsize,类型与src相同
– flag表示插值方法的组合和可选值
– borderValue表示像素外推法,当borderMode = BORDER_TRANSPARENT时,表示目标图像中的像素不会修改源图像中的“异常值”。
– borderValue用于边界不变的情况,默认情况下为0
下面代码是图像平移的一个简单案例,它定义了图像平移矩阵M,然后调用warpAffine()函数将原始图像垂直向下平移了50个像素,水平向右平移了100个像素。
# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('scenery.png') #图像平移矩阵 M = np.float32([[1, 0, 100], [0, 1, 50]]) #获取原始图像列数和行数 rows, cols = src.shape[:2] #图像平移 result = cv2.warpAffine(src, M, (cols, rows)) #显示图像 cv2.imshow("original", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()
输出结果如图6-3所示:
下面一个案例是将图像分别向下、向上、向右、向左平移,再调用matplotlib绘图库依次绘制的过程。
# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #读取图片 img = cv2.imread('scenery.png') image = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #图像平移 #垂直方向 向下平移100 M = np.float32([[1, 0, 0], [0, 1, 100]]) img1 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) #垂直方向 向上平移100 M = np.float32([[1, 0, 0], [0, 1, -100]]) img2 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) #水平方向 向右平移100 M = np.float32([[1, 0, 100], [0, 1, 0]]) img3 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) #水平方向 向左平移100 M = np.float32([[1, 0, -100], [0, 1, 0]]) img4 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) #循环显示图形 titles = [ 'Image1', 'Image2', 'Image3', 'Image4'] images = [img1, img2, img3, img4] for i in range(4): plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
输出结果如图6-4所示,它从四个方向都进行了平移,并且调用subplot()函数将四个子图绘制在一起。
三.图像缩放
图像缩放(image scaling)是指对数字图像的大小进行调整的过程。在Python中,图像缩放主要调用resize()函数实现,函数原型如下:
- result = cv2.resize(src, dsize[, result[. fx[, fy[, interpolation]]]])
– src表示原始图像
– dsize表示图像缩放的大小
– result表示图像结果
– fx表示图像x轴方向缩放大小的倍数
– fy表示图像y轴方向缩放大小的倍数
– interpolation表示变换方法。CV_INTER_NN表示最近邻插值;CV_INTER_LINEAR表示双线性插值(缺省使用);CV_INTER_AREA表示使用像素关系重采样,当图像缩小时,该方法可以避免波纹出现,当图像放大时,类似于CV_INTER_NN;CV_INTER_CUBIC表示立方插值
常见的图像缩放两种方式如下所示,第一种方式是将原图像设置为(160, 160)像素大小,第二种方式是将原始图像缩小为0.5倍。
- result = cv2.resize(src, (160,160))
- result = cv2.resize(src, None, fx=0.5, fy=0.5)
设(x1, y1)是缩放后的坐标,(x0, y0)是缩放前的坐标,sx、sy为缩放因子,则图像缩放的计算公式(6-3)所示:
下面是Python实现图像缩放的代码,它将所读取的风景图像进行缩小。
# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('scenery.png') #图像缩放 result = cv2.resize(src, (200,100)) print(result.shape) #显示图像 cv2.imshow("original", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()
输出结果如图6-5所示,图像缩小为(100, 200, 3)像素。注意,代码中调用函数 cv2.resize(src, (200,100)) 设置新图像大小dsize的列数为200,行数为100。
下面讲解另一种图像缩放变换的方法,通过原始图像像素乘以缩放系数进行图像变换,代码如下:
# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('scenery.png') rows, cols = src.shape[:2] print(rows, cols) #图像缩放 dsize(列,行) result = cv2.resize(src, (int(cols*0.6), int(rows*1.2))) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) cv2.waitKey(0) cv2.destroyAllWindows()
获取图片“scenery.png”的元素像素值,其rows值为384,cols值为512,接着进行宽度缩小0.6倍、高度放大1.2倍的处理,运行前后对比效果如图6-6所示。
最后讲解调用(fx,fy)参数设置缩放倍数的方法,对原始图像进行放大或缩小操作。下面代码是fx和fy方向缩小至原始图像0.3倍的操作。
# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('scenery.png') rows, cols = src.shape[:2] print(rows, cols) #图像缩放 result = cv2.resize(src, None, fx=0.3, fy=0.3) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()
输出的结果如图6-7所示,这是按比例0.3×0.3缩小的。
四.图像旋转
图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。图像旋转变换会有一个旋转中心,这个旋转中心一般为图像的中心,旋转之后图像的大小一般会发生改变。图6-8表示原始图像的坐标(x0, y0)旋转至(x1, y1)的过程。
旋转公式如(6-4)所示,其中(m,n)是旋转中心,a是旋转的角度,(left,top)是旋转后图像的左上角坐标。
图像旋转变换主要调用getRotationMatrix2D()函数和warpAffine()函数实现,绕图像的中心旋转,函数原型如下:
-
M = cv2.getRotationMatrix2D(center, angle, scale)
– center表示旋转中心点,通常设置为(cols/2, rows/2)
– angle表示旋转角度,正值表示逆时针旋转,坐标原点被定为左上角
– scale表示比例因子 -
rotated = cv2.warpAffine(src, M, (cols, rows))
– src表示原始图像
– M表示旋转参数,即getRotationMatrix2D()函数定义的结果
– (cols, rows)表示原始图像的宽度和高度
实现代码如下所示:
# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 src = cv2.imread('scenery.png') #源图像的高、宽 以及通道数 rows, cols, channel = src.shape #绕图像的中心旋转 #函数参数:旋转中心 旋转度数 scale M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1) #函数参数:原始图像 旋转参数 元素图像宽高 rotated = cv2.warpAffine(src, M, (cols, rows)) #显示图像 cv2.imshow("src", src) cv2.imshow("rotated", rotated) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()
显示效果如图6-9所示,绕图像中心点逆时针旋转30度。
五.总结
本章主要讲解Python和OpenCV的图像几何变换,详细介绍了图像平移、图像缩放和图像旋转,这些知识点也是我们PC端或手机端图像处理应用常见的算法,读者可以尝试结合这些应用完成一套图像处理软件。
最近寒假日更,为了感谢读者。同时感谢在求学路上的同行者,不负遇见,勿忘初心。图像处理系列主要包括三部分,分别是:
这周的留言感慨~
十二年CSDN的博客分享,如果要说分享最让我开心的是什么?不是传道,不是授业,也不是解惑,而是接下来这类事。这些年已经陆续鼓励了一些朋友当老师,而昨天得知这一位博友真的去到新疆南疆成为了一名小学老师,我很是感动,是真的感动,六年前我曾鼓励他如果想,就放弃高额工资的互联网大厂,去做自己想做的,没想到已经当了四年老师。又当爹又当妈,国语普及,文化教育,这里面的艰辛不是一两句道得清,除了佩服就是鼓励。
正如你说的一样,“一辈子总得做点有意义的事情,生命实在太短暂,一定要活得积极、正面”。或许,这也是我在CSDN分享博客的最大意义,再比如云南那位老友的留言,“农村的孩子下雨没有伞,只能拼命奔跑”,希望你以后也能成为一名教师,感恩有你们,感谢有你们。我也希望自己早日毕业回到家乡,花上三四十年做好两件事,一是认真教书,二是将少数民族文物抢救和文字语音保护做好,也鼓励更多人一起加入进来。自己虽然很菜吧,但还是有一些喜欢的事,尤其陪伴爱的人,挺好,爱你们喔。2022年继续加油,在CSDN分享更高质量的博客和专栏。
(By:娜璋之家 Eastmount 2022-01-27 夜于贵阳 https://blog.csdn.net/Eastmount )
参考文献:
- [1]冈萨雷斯. 数字图像处理(第3版)[M]. 北京:电子工业出版社, 2013.
- [2]阮秋琦. 数字图像处理学(第3版)[M]. 北京:电子工业出版社,2008.
- [3]毛星云, 冷雪飞. OpenCV3编程入门[M]. 北京:电子工业出版社, 2015.
- [4]Eastmount. [Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移[EB/OL]. (2018-09-06). https://blog.csdn.net/Eastmount/article/details/82454335.
- [5]Eastmount. [数字图像处理] 六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解[EB/OL]. (2015-06-04). https://blog.csdn.net/Eastmount/article/details/46345299.
-
c++图像处理几何变换
2018-10-15 12:32:02图像区域旋转缩放平移几何变换,形状绘制直线圆等C++接口和大概思路,重在应用吧. 本人空闲只抽点时间仓促写下。 -
bmp图像几何变换(近邻值、双线性、三次卷积)
2016-07-08 17:57:22资源关于bmp图片的几何变换,包括:旋转,缩放,近邻值,双线性,三次卷积;适合图像处理初学者学习,算法可能不是很精确,见谅! 刚好最近在学习这个,网上找了很多资料,不是很全,所以自己写了一个上传,仅供参考 -
图像几何变换与畸变校正算法研究与实现.ppt
2020-07-06 14:14:04图像几何变换与畸变校正算法研究与实现.ppt -
数字图像处理之图像几何变换
2021-05-08 10:48:17图像的几何变换包括以下几个方面: 导入库 import numpy as np import matplotlib.pyplot as plt import cv2 as cv 显示图片函数 def show(img): if img.ndim == 2: plt.imshow(img,cmap='gray') else: plt....图像的几何变换包括以下几个方面:
导入库import numpy as np import matplotlib.pyplot as plt import cv2 as cv
显示图片函数
def show(img): if img.ndim == 2: plt.imshow(img,cmap='gray') else: plt.imshow(cv.cvtColor(img,cv.COLOR_RGB2BGR)) plt.show()
图片的剪裁、放大和缩小
#图片剪裁 img = cv.imread('C:\PerfLogs\pc4.jpg') img_pg = img[1250:1750,300:1000,:] show(img_pg) #opencv中自带的resize函数 img2 = cv.resize(img,(500,400)) show(img2)
原图:
剪裁过后:
调整大小:
平移变换
平移矩阵:#平移变换 M = np.array([ [1,0,100], [0,1,50] ],dtype=np.float32)#平移矩阵 img2 = cv.warpAffine(img,M,(1333,2003))#原图、偏移矩阵、变换后的图片大小 show(img2)
错切变换
其实错切变换和平移变换的公式是一样的,只不过矩阵的参数不同,可以根据平移变换来考虑错切变换。#水平错切变换 M = np.array([ [1,0.2,0], [0,1,0] ],dtype=np.float32) img3 = cv.warpAffine(img,M,(2333,2203)) show(img3) #垂直错切变换 M = np.array([ [1,0,0], [0.3,1,0] ],dtype=np.float32) img3 = cv.warpAffine(img,M,(2333,2203)) show(img3)
水平错切:
垂直错切:
镜像变换
考虑对称性#水平镜像变换 Mx = np.array([ [-1,0,930], [0,1,0] ],dtype=np.float32) img4 = cv.warpAffine(img,Mx,(3333,2203)) show(img4) #垂直镜像变换 Mx = np.array([ [1,0,0], [0,-1,1200] ],dtype=np.float32) img4 = cv.warpAffine(img,Mx,(1333,2203)) show(img4)
上面的代码是自己写的变换矩阵,然后实现的镜像变换。其实opencv中是有自带的库函数进行镜像变换的。但是实际使用的时候,可能需要根据不同的对称线进行镜像变换,所以学会变换矩阵的做法也是很必要的。
#镜像变换函数 img4 = cv.flip(img ,1)#水平镜像变换 img5 = cv.flip(img ,0)#垂直镜像变换 img6 = cv.flip(img ,-1)#中心镜像变换 show(np.hstack([img4,img5,img6]))
旋转变换
公式推导:
#旋转变换 beta = np.pi / 4.0 M = np.array([ [np.cos(beta),np.sin(beta),0], [-np.sin(beta),np.cos(beta),0] ],dtype=np.float32) img5 = cv.warpAffine(img,M,(4333,2203)) show(img5)
opencv自带的库函数进行旋转变换-利用opencv自带的库函数求出变换矩阵
#opencv函数进行旋转变换 h,w,c = img.shape M2 = cv.getRotationMatrix2D((w//2,h//2),45,1)#中心点、角度、放大还是缩小 img5 = cv.warpAffine(img,M2,(1333,1203))
opencv自带的库函数直接实现旋转变换,但是只能是特殊角度的旋转,例如90°,180°。img6 = cv.rotate(img,cv.ROTATE_90_CLOCKWISE) show(img6)
透视变换
所谓的透视变换就是将图片偏向正视角的部分朝向正视角。如下所示:
#透视变换 img = cv.imread('C:\PerfLogs\pp.jpg') src = np.array([ [210,50], [610,270], [650,470], [150,450] ],dtype=np.float32)#想透视变换的部分,在原图中的四角坐标,左上-右上-右下-左下 dst = np.array([ [150,50], [650,50], [650,470], [150,470] ],dtype=np.float32)#透视变换之后的部分,在生成的图片中的四角坐标,左上-右上-右下-左下 M = cv.getPerspectiveTransform(src,dst) img2 = cv.warpPerspective(img,M,(1500,1500)) show(img2)
-
Python 计算机视觉(五)—— OpenCV 进行图像几何变换
2021-10-16 18:49:28这篇文章中简单总结了图像几何变换中的平移变换、旋转变换、缩放变换、镜像变换以及仿射变换这五个部分,并介绍了它们的原理;其中参考的一些文章已经添加了链接,如果想进行更加全面的学习可以点进去进行查看。 -
常见的图像几何变换
2021-08-08 21:22:25图像的几何变换又称为图像空间变换, 它将一幅图像中的坐标位置映射到另一幅图像中的 新坐标位置。常见的几何变换包括旋转、平移、缩放、镜像、转置、错切等,以及几种组合变换,如刚体变换、仿射变换、单应变换 ... -
图像几何变换和图像变换的区别
2020-07-12 16:55:04图像几何变换:改变图像的大小和形状,比如图像的平移、旋转、放大、缩小等这些方法在图像配准中使用较多。 图像转换:通过数学映射的方法,将空域的图像信息转换到频域,时域等空间上进行分析,比如傅里叶变换,... -
图像几何变换的DSP算法研究与实现
2021-01-19 19:05:21其中数字扫描变换的精度直接影响图像的分辨率和几何失真度,变换算法的复杂度直接影响图像处理运算量和图像处理的实时性,也直接影响后续图像处理的质量。 DSP易于满足图像处理中运算量大、精度高、实时性强、... -
图像几何变换原理
2019-11-22 15:57:12图像变换原理 在三维中,通过光源照射下,不断变换光源,则在投影中得到不同的结果。 1. 缩放 只变换矩阵的光源的位置,把光源拉近放远,则投影得到缩放的图像,达到调整图像大小的作用,下面示意图是按比例缩放的... -
C++实现图像几何变换
2014-11-06 16:23:12用C++实现图像的变换,包括平移,旋转,镜像,转置等 -
图像几何变换(C++)代码(平移、镜像、转置、缩放、旋转)
2013-09-12 17:40:37图像几何变换(C++)代码(实现平移、镜像、转置、缩放、旋转),代码运行通过,没问题 -
MATLAB--数字图像处理 图像几何变换
2019-12-12 22:33:362.掌握图像几何变换的原理及数学运算。 3.于MATLAB环境下编程实现对图片不同的几何变换。 三、实验内容 1.将图像绕图像中心顺时针旋转30度,旋转之后的图像尺寸保持为原图像的尺寸。 2.将原图像放大2倍 3.得到该图像... -
数字图像几何变换_三种插值算法_最邻近_二次插值_双三次插值_matlab
2022-03-31 13:57:58资源名:数字图像几何变换_三种插值算法_最邻近_二次插值_双三次插值_matlab 资源类型:matlab项目全套源码 源码说明: 全部项目源码都是经过测试校正后百分百成功运行的,如果您下载后不能运行可联系我进行指导或者... -
计算机图像处理实验七:图像几何变换技术(MATLAB)
2021-06-12 20:44:49【实验名称】 图像几何变换技术 【实验目的】