pyhton:图像旋转
最近一个作业中要用到图像旋转,分享一下学习过程。如有讲错的地方,恳请指正!
图像旋转,想想真简单啊,不就是将图像矩阵乘上一个旋转平移矩阵就完了吗?实际上还真没这么简单。首先这个旋转平移矩阵怎么获得?通过这篇博客我们能够轻松理解这个过程。http://www.cnblogs.com/xianglan/archive/2010/12/26/1917247.html
该旋转平移矩阵可以通过以图像左上角为原点的矩阵坐标系转换到以图像中心为原点的笛卡尔坐标系,再乘上一个旋转矩阵,再将旋转后的图像转换到原点矩阵坐标系。
当然,通过实验我也获得了该博客中所提到的蜂窝点。



当然要获得完整的图片,这篇博文也有程序。针对蜂窝点,我尝试中值滤波,但使用cv2.medianBlur(iLRotate30, 3)对图像滤波时,总是报错
cv2.error: ..\..\..\opencv-2.4.13\modules\imgproc\src\smooth.cpp:1695: error: (-210) in function cv::medianBlur
搞了半天,不知为啥,尴尬只好自己写了一个中值滤波。顺便把本文中的cv程序改成cv2方便对图像数据的处理。
import cv2
import math
from numpy import *
import numpy as np def rotate(image, angle):
rows, cols, nchan = np.shape(image)
anglePi = angle * math.pi / 180.0
cosA = math.cos(anglePi)
sinA = math.sin(anglePi)
X1 = math.ceil(abs(0.5 * rows * cosA + 0.5 * cols * sinA))
X2 = math.ceil(abs(0.5 * rows * cosA - 0.5 * cols * sinA))
Y1 = math.ceil(abs(-0.5 * rows * sinA + 0.5 * cols * cosA))
Y2 = math.ceil(abs(-0.5 * rows * sinA - 0.5 * cols * cosA))
rows_new = int(2 * max(Y1, Y2))
cols_new = int(2 * max(X1, X2))
iLrotate = zeros((rows_new + 1, cols_new + 1, nchan), dtype=uint8)
for i in xrange(rows):
for j in xrange(cols):
x = int(cosA * i - sinA * j - 0.5 * cols * cosA + 0.5 * rows * sinA + 0.5 * cols_new)
y = int(sinA * i + cosA * j - 0.5 * cols * sinA - 0.5 * rows * cosA + 0.5 * rows_new)
# if x > -1 and x < rows and y > -1 and y < cols:
iLrotate[x, y] = image[i, j]
return iLrotate
def rgb2gray(im):
gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140
return gray
def medianFilter(image,size):
rows, cols, nchan = image.shape
b = size / 2
index_median = (size**2 - 1)/2
for i in xrange(b, rows - b):
for j in xrange(b, cols - b):
for k in xrange(nchan):
temp = image[i-b:i+b+1, j-b:j+b+1, k].ravel()
temp = sorted(temp)
image[i, j, k] = temp[index_median]
return image
if __name__ == "__main__":
image = cv2.imread('lena.jpg')
iLRotate30 = rotate(image, 30)
iLRotate90 = rotate(image, 90)
cv2.imshow('image', image)
iLRotate30_blur = cv2.medianBlur(iLRotate30, 3)
iLRotate90_blur = medianFilter(iLRotate90, 3)
cv2.imshow('iLRotate30', iLRotate30_blur)
cv2.imshow('iLRotate90', iLRotate90_blur)
cv2.waitKey(0)



虽然,没有蜂窝点了,但是图片信息有损失,而且很明显。为啥用opencv或者PIL旋转后的图像没有蜂窝点,且清洗度不减弱?
from PIL import Image
import matplotlib.pyplot as plt
pil_im = Image.open('lena.jpg')
plt.imshow(pil_im)
plt.show()
pil_im1 = pil_im.rotate(30)
plt.axis('off')
pil_im1.save('./ImageProcessed/rotated30_PIL.png')
plt.imshow(pil_im1)
plt.show()
pil_im2 = pil_im.rotate(90)
plt.axis('off')
pil_im2.save('./ImageProcessed/rotated90_PIL.png')
plt.imshow(pil_im2)
plt.show()


import cv2
import matplotlib.pyplot as plt
img = cv2.imread('lena.jpg')
# img = img / 255.0
rows, cols = img.shape[:2]
#第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例
M1 = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)
M2 = cv2.getRotationMatrix2D((cols/2, rows/2), 90, 1)
#第三个参数:变换后的图像大小
res1 = cv2.warpAffine(img, M1, (rows, cols))
res2 = cv2.warpAffine(img, M2, (rows, cols))
cv2.imwrite('./ImageProcessed/rotated30_cv2.png', res1)
cv2.imwrite('./ImageProcessed/rotated90_cv2.png', res2)
cv2.imshow('Ori', img)
cv2.imshow('Rotated1', res1)
cv2.imshow('Rotated2', res2)


这两种旋转方式相比之下,我更喜欢后者。因为,可以调整图像旋转中心位置,和缩放的比例。python下opencv图像变换的详细介绍可以看这两篇博客。http://www.myexception.cn/image/1958561.html
http://www.tuicool.com/articles/rq6fIn
至于为啥这两种方法效果比自己写的好,可能是因为它们对旋转后的图像先差值后滤波。(仅是我的猜测而已,改天看看别人的源码就清楚了)
pyhton:图像旋转的更多相关文章
- NOI题库 09:图像旋转翻转变换
NOI题库开始的题,也是略水,当然也是大水,所以彼此彼此 09:图像旋转翻转变换 总时间限制: 1000ms 内存限制: 65536kB 描述 给定m行n列的图像各像素点灰度值,对其依次进行一系列操作 ...
- 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起
话说,平凡之处显真格,这一点也没错! 比如,对旋转图像进行双线性插值,很简单吧? 可,对我,折腾了大半天,也没有达到预期效果! 尤其是三个误区让我抓瞎好久: 1,坐标旋转公式. 这东西,要用 ...
- opencv 图像仿射变换 计算仿射变换后对应特征点的新坐标 图像旋转、缩放、平移
常常需要最图像进行仿射变换,仿射变换后,我们可能需要将原来图像中的特征点坐标进行重新计算,获得原来图像中例如眼睛瞳孔坐标的新的位置,用于在新得到图像中继续利用瞳孔位置坐标. 仿射变换在:http:// ...
- Opencv2.4.4作图像旋转和缩放
关于下面两个主要函数的讲解: cv::getRotationMatrix2D(center, angle, scale); cv::warpAffine(image, rotateImg, rotat ...
- 每日算法37:Rotate Image (图像旋转)
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- [google面试CTCI] 1-6.图像旋转问题
[字符串与数组] Q:Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, wr ...
- CCF CSP 201503-1 图像旋转 (降维)
题目链接:http://118.190.20.162/view.page?gpid=T27 问题描述 试题编号: 201503-1 试题名称: 图像旋转 时间限制: 5.0s 内存限制: 256.0M ...
- 图像旋转、伸缩的自写matlab实现
一.图像的旋转 今天的代码不是自己写的,缺少一些时间.但是认认真真推导了一下旋转的公式,代码的思想与原博博主一致,致敬! 愚以为,自己来实现图像旋转算法的关键点有二:其一,确定旋转后的图像边界.其二, ...
- 图像旋转与图像缩放及Matlab代码实现
本周的作业是自己通过公式编写图像旋转与缩放的代码.今天先通过调用函数的方法来实现. 图像的旋转: A=imread('2.jpg'); J=imrotate(A, 30); subplot(1,2,1 ...
随机推荐
- Anaconda更新和第三方包更新
更新Anaconda和它所包含的包 1.打开cmd,切换到Anaconda的Scripts目录下:./Anaconda3/Scripts 2.更新Anaconda conda update conda ...
- “Project 'MyFunProject' is not a J2SE 5.0 compliant project.”
- Hyperledger Fabric Membership Service Providers (MSP)——成员服务
Membership Service Providers (MSP) 本文将介绍有关MSPs的设置和最佳实践的详细方案. Membership Service Providers (MSP)是一个旨在 ...
- Docker镜像导致centos-root根分区容量爆满
当虚拟机服务器运行Docker久了后,发现Docker的文件越来越大,某天发现此台机上的数据库访问不了了,再重启数据库等日志,提示空间不足,查看磁盘空间: root分区满载啊,前段时间还有不少空间的, ...
- tomcat 部署war项目
前提是 jdk环境已配好 把项目war包放到tomcat的webapps目录下 启动tomcat: 这里我把8080端口修改成了80 IP也修改了 如果没修改直接输入localhost:8080/te ...
- BOM基础知识
1.什么是BOM BOM(Browser Object Document)即浏览器对象模型. BOM提供了独立于内容 而与浏览器窗口进行交互的对象: 由于BOM主要用于管 ...
- 汇编编译器(masm.exe)对jmp的相关处理
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 苹果系统css样式变化
原因:苹果自带样式覆盖了 参考文章比较详细,就不自己写了,copy了一份~~~ @参考文章 只要在样式里面加一句去掉css去掉iPhone.iPad的默认按钮样式就可以了!~ input[type=& ...
- 在Tomcat中配置连接池和数据源
1.DataSource接口介绍 (1)DataSource 概述 JDBC1.0原来是用DriverManager类来产生一个对数据源的连接.JDBC2.0用一种替代的方法,使用DataSource ...
- Apache配置虚拟主机后,不能访问localhost
解决方法:将localhost设为虚拟域名 重要的是要注释掉httpd.conf文件的ServerName localhost:80