最近一个作业中要用到图像旋转,分享一下学习过程。如有讲错的地方,恳请指正!

图像旋转,想想真简单啊,不就是将图像矩阵乘上一个旋转平移矩阵就完了吗?实际上还真没这么简单。首先这个旋转平移矩阵怎么获得?通过这篇博客我们能够轻松理解这个过程。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:图像旋转的更多相关文章

  1. NOI题库 09:图像旋转翻转变换

    NOI题库开始的题,也是略水,当然也是大水,所以彼此彼此 09:图像旋转翻转变换 总时间限制: 1000ms 内存限制: 65536kB 描述 给定m行n列的图像各像素点灰度值,对其依次进行一系列操作 ...

  2. 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起

    话说,平凡之处显真格,这一点也没错!  比如,对旋转图像进行双线性插值,很简单吧?  可,对我,折腾了大半天,也没有达到预期效果!  尤其是三个误区让我抓瞎好久: 1,坐标旋转公式.   这东西,要用 ...

  3. opencv 图像仿射变换 计算仿射变换后对应特征点的新坐标 图像旋转、缩放、平移

    常常需要最图像进行仿射变换,仿射变换后,我们可能需要将原来图像中的特征点坐标进行重新计算,获得原来图像中例如眼睛瞳孔坐标的新的位置,用于在新得到图像中继续利用瞳孔位置坐标. 仿射变换在:http:// ...

  4. Opencv2.4.4作图像旋转和缩放

    关于下面两个主要函数的讲解: cv::getRotationMatrix2D(center, angle, scale); cv::warpAffine(image, rotateImg, rotat ...

  5. 每日算法37:Rotate Image (图像旋转)

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  6. [google面试CTCI] 1-6.图像旋转问题

    [字符串与数组] Q:Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, wr ...

  7. CCF CSP 201503-1 图像旋转 (降维)

    题目链接:http://118.190.20.162/view.page?gpid=T27 问题描述 试题编号: 201503-1 试题名称: 图像旋转 时间限制: 5.0s 内存限制: 256.0M ...

  8. 图像旋转、伸缩的自写matlab实现

    一.图像的旋转 今天的代码不是自己写的,缺少一些时间.但是认认真真推导了一下旋转的公式,代码的思想与原博博主一致,致敬! 愚以为,自己来实现图像旋转算法的关键点有二:其一,确定旋转后的图像边界.其二, ...

  9. 图像旋转与图像缩放及Matlab代码实现

    本周的作业是自己通过公式编写图像旋转与缩放的代码.今天先通过调用函数的方法来实现. 图像的旋转: A=imread('2.jpg'); J=imrotate(A, 30); subplot(1,2,1 ...

随机推荐

  1. 010 有顺序的Map的实现类:TreeMap和LinkedHashMap

    作者:nnngu GitHub:https://github.com/nnngu 博客园:http://www.cnblogs.com/nnngu 简书:https://www.jianshu.com ...

  2. Winform & Devexpress Chart使用入门

    一.Chart(Winform) 使用图表控件(chart)首先要理解图表区域(ChartArea).XY轴(AxisX.AxisY).数据点(Series).标题(Title).图例(Legend) ...

  3. Spider_Man_5.2 の Mongodb_使用

    一:简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库1.易用性 MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库.不采用关系型主要是为了获得 ...

  4. UE4 分层材质 Layerd Materials

    在UE4中最正规的材质制作流程就像: 建立新材质,并将其调整为达至完美. 在内容浏览器中,建立新材质函数,并将所有材质函数节点复制/粘贴到其中. 将网络连接到新的 Make Material Attr ...

  5. c++---天梯赛---N个数求和

    ★题目: ★难点:要求只能以有理数和分数去输出结果. ★分析:可以对输入的数据进行通分处理,随后把结果按格式输出. ★代码: #include<iostream> #include< ...

  6. curl说明

    https://baike.baidu.com/item/curl/10098606?fr=aladdin curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多种L ...

  7. 见微知著——从自定义类型的operator==说起

    今天打算用C++模拟一下Java的Object对象.需求很简单,通过一个自定义用户类型包装一个内建类型,并提供equals.hashCode.=和== 4种函数. 源码如下: #pragma once ...

  8. 邓_tp_笔记

    <?phpnamespace app\teacher\controller;use think\Db;use app\common\model\Classcourse;use app\commo ...

  9. 数据库复习总结(6)-SQL语句入门(脚本、命令)

    脚本操作: 脚本操作 注释:--单行注释,/**/多行注释 数据库:创建.删除 (可以通过查看master数据库中的sysdatabase表,来了解当前存在的数据库) 点击“新建查询”,选中哪句执行哪 ...

  10. vue源码入口文件分析

    开发vue项目有段时间了, 之前用angularjs 后来用 reactjs 但是那时候一直没有时间把自己看源码的思考记录下来,现在我不想再浪费这 来之不易的思考, 我要坚持!! 看源码我个人感觉非常 ...