图像旋转后出现黑点 - (二) - 填坑

前接:图像旋转后出现黑点 - (一) - 入坑

这是填坑篇,之前写的图片旋转程序把图片变成了桌布,几个世纪后,在一个月黑风高的夜晚,我灵光乍现,何不试试双线性插值?

先上代码和效果图。

 1 # !/usr/bin/env python3
 2 # -*-coding:utf-8-*-
 3 """
 4 双线性插值参考资料: 双线性插值原理及Python实现 - Jinglever  https://www.jianshu.com/p/29e5c84ea539
 5
 6 如果出现错误:...If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config
 7 执行 pip3 install opencv-contrib-python
 8 """
 9 import numpy as np
10 # np.set_printoptions(suppress=True)    # 关闭科学计数法
11 import cv2
12 import os
13
14
15 # 旋转矩阵R
16 ANGLE = 30  # (dim=°)
17 assert 0 < ANGLE < 90   # 目前限制这个旋转范围,原因是y1, y2, y3, y4上下关系根据角度变化
18 alpha = ANGLE/360*2*np.pi
19 R_rev = np.matrix([[np.cos(alpha), np.sin(alpha)],      # 逆向映射推导的旋转矩阵
20                 [-np.sin(alpha), np.cos(alpha)]])
21 print(R_rev)
22
23 # 重设图片大小
24 WIDTH, HEIGHT = 640, 480
25
26 img = cv2.imread("timg.jpg")
27 img = cv2.resize(img, (WIDTH, HEIGHT))
28 # img_gray = np.float32(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
29 img = np.float32(img)
30 print(img.shape)
31
32 # 假设已经得到旋转后的图片,利用图片边框画出图片的矩形,在矩形内遍历坐标就是图片各个像素点的坐标
33 # 注意旋转角度超过90度后边框线的上下关系会发生变化,待改进……
34 x = np.arange(np.abs(WIDTH*np.cos(alpha)) + np.abs(HEIGHT*np.sin(alpha)), dtype=np.int32)
35 y1 = lambda x: (- x*np.tan(alpha)).astype(np.int32)
36 y2 = lambda x: (y1(x) + HEIGHT/np.cos(alpha)).astype(np.int32)
37 y3 = lambda x: (x/np.tan(alpha)).astype(np.int32)
38 y4 = lambda x: (y3(x) - WIDTH/np.sin(alpha)).astype(np.int32)
39 # 用矩形下面2条线(的最大值)确定y坐标最小值,上面2条线(的最小值)确定y坐标最大值
40 y_min = np.max(np.concatenate((y1(x).reshape(1, -1), y4(x).reshape(1, -1))), axis=0)
41 y_max = np.min(np.concatenate((y2(x).reshape(1, -1), y3(x).reshape(1, -1))), axis=0)
42 # 计算旋转后图片各像素点坐标
43 pre_index = [np.array((yi, xi)).reshape(-1, 1) for xi in x for yi in range(y_min[xi], y_max[xi]+1)]
44
45 ori_index = np.array(list(map(R_rev.dot, pre_index))).reshape(-1, 2)     # 坐标变换到原图
46 hs_p, ws_p = np.hsplit(ori_index, 2) # 分离y, x坐标
47
48 ws_p = np.clip(ws_p, 0, WIDTH-1)  # 限制坐标最值防止越界
49 hs_p = np.clip(hs_p, 0, HEIGHT-1)
50
51 ws_0 = np.clip(np.floor(ws_p), 0, WIDTH - 2).astype(np.int)     # 找出每个投影点在原图的近邻点坐标
52 hs_0 = np.clip(np.floor(hs_p), 0, HEIGHT - 2).astype(np.int)
53 ws_1 = ws_0 + 1
54 hs_1 = hs_0 + 1
55
56 f_00 = img[hs_0, ws_0, :].T    # 四个临近点的像素值
57 f_01 = img[hs_0, ws_1, :].T
58 f_10 = img[hs_1, ws_0, :].T
59 f_11 = img[hs_1, ws_1, :].T
60
61 w_00 = ((hs_1 - hs_p) * (ws_1 - ws_p)).T    # 计算权重
62 w_01 = ((hs_1 - hs_p) * (ws_p - ws_0)).T
63 w_10 = ((hs_p - hs_0) * (ws_1 - ws_p)).T
64 w_11 = ((hs_p - hs_0) * (ws_p - ws_0)).T
65
66 pixels = (f_00 * w_00).T + (f_01 * w_01).T + (f_10 * w_10).T + (f_11 * w_11).T  # 计算目标像素值
67
68 y_new, x_new = np.hsplit(np.array(pre_index).reshape(-1, 2), 2) # # 分离y, x坐标
69 y_new = y_new - np.min(y_new)      # y坐标平移,防止图片旋转后被窗口切分
70
71 h, w = np.max(y_new), np.max(x_new)    # 旋转后画布大小
72 # 像素映射 原始→新图
73 new_img = np.zeros((h+1, w+1, img.shape[2]))    # (H, W, C)
74 new_img[y_new, x_new, :] = pixels   # 填充像素
75
76 cv2.imwrite(‘./AffinedImg.jpg‘, new_img, [int(cv2.IMWRITE_JPEG_QUALITY),95])
77 # 显示图片
78 cv2.imshow(‘img‘, np.array(new_img, dtype=np.uint8))
79 cv2.waitKey(0)
80 cv2.destroyAllWindows()

原图见入坑篇。

下面是运行结果,这次我换成了彩色的:

...讲解?最近忙成球,正在紧张编辑中,敬请期待……;-)

原文地址:https://www.cnblogs.com/adjwang/p/12227576.html

时间: 2024-07-29 23:34:46

图像旋转后出现黑点 - (二) - 填坑的相关文章

用OpenCV实现Photoshop算法(一): 图像旋转

最近学习了OpenCV,于是想用它实现Photoshop的主要功能,用于照片处理. 对于一张照片,PS的一般处理步骤包括: 1, 旋转图片,校正位置. 2,剪切,调整大小,重新构图. 3,调整色阶.曲线,使图片曝光正确.对比适中. 4,调整对比度.饱和度 5,印章去掉不想要的东西,液化调整形体线条 6,对于人像图片,美肤.美白 7, 用色彩平衡.可选颜色等调整色调,形成照片调性 8,加一些光效 9,锐化 以后的一系列博文将采用OpenCV逐一实现Photoshop的算法和功能, 并用计算机视觉人

C/C++ BMP(24位真彩色)图像处理(4)------图像の旋转

历经一个多月,CSDN貌似终于好像把文章列表阅读量信息归零BUG给修好了,于是乎放篇做期末大作业时写的文章上来测测效果,可别又像上次一样一发文章就又坑爹了啊! 本篇谈的是图像的旋转,不算是什么新鲜的题目了.但是现在由于很多工具如MATLAB.OPENCV等都把算法写好给用户调用,导致大多用户只知其然不知其所以然,所以回顾一下也是好的. 图像的旋转,说到底就是每个像素点绕着某个圆心旋转一定角度.如果是写代码的话,旋转的角度和圆心应该是已知的条件,我们第一个思路是根据已知条件求取出图像经过旋转后的新

关于图像旋转以及旋转后对应像素的位置

参考链接:http://www.echojb.com/image/2016/11/14/258268.html 一.首先来说一下关于像素旋转一定角度后的对应位置: (1)旋转中心为左上角原点: 旋转有一个绕什么转的问题.我们先来看最简单的,绕第一个像素转,则旋转的情况会像这样: 令旋转前有 旋转a角度后有 以矩阵形式表示为 (2)旋转中心为图像中心: 当图片较大时,计算会很慢.主要是判断和计算太多了这里只讨论图像处理,程序的优化暂时放一边运行结果如下: 我们能看到,旋转后的图像有很多“蜂窝煤”.

Django2.1集成xadmin管理后台所遇到的错误集锦,解决填坑(二)

django默认是有一个admin的后台管理模块,但是丑,功能也不齐全,但是大神给我们已经集成好了xadmin后台,我们拿来用即可,但是呢,django已经升级到2.1版本了,xadmin貌似跟不上节奏,那么在集成过程中咱就一步一步填坑吧,这也是一种学习的过程,遇到错误,找到错误的地方,看看django最新升级都修改了那些,去掉了那些,把相应出错的地方替换即可. xadmin源码地址:https://github.com/sshwsfc/xadmin 下载并解压: 我们用到的是xadmin文件夹

H5填坑笔记--持续更新

最近一直在做移动端的页面,发现很多的坑,这里做一下总结,填填坑…… css常见的问题(一) 一.iOS键盘首字母自动大写 IOS的机子,默认英文输入法状态下,首字母是自动大写的,有时候挺烦人的. 在iOS中,默认情况下键盘是开启首字母大写的功能的,如果业务不想出现首字母大写,可以这样: <input type="text" autocapitalize="off" /> 二.iOS输入框默认内阴影和样式问题 在iOS上,输入框默认有内部阴影,但无法使用

css 填坑常用代码分享

以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. /*强制不换行*/ white-space:nowrap; /*自动换行*/ word-wrap: break-word; word-break: normal; /*强制英文单词断行*/ word-break:break-all; 2. 两端对齐 text-align:justify;text-justify:inter-ideogra 3. 去掉Webkit(chrome)浏览器中input(文本框)或texta

填坑——浅谈“离散时间信号的傅里叶变换”

之前学习计算机视觉,虽然敲了不少代码,但一直没弄懂傅里叶变换以及图像滤波背后的数学含义,只能对着现成的公式照葫芦画瓢,让我内心觉得深深的不安.好在通过这段时间在华为的实习,恶补了一下数字信号处理相关的基础知识,总算是把这方面的坑给填上了.以下为这几天的学习成果,也就是我自己对傅里叶变换的理解. 一.离散时间信号 要弄懂离散时间信号的傅里叶变换,首先要弄清楚什么是信号,而什么又是离散时间信号.(虽然感觉像是废话,可作为一个软件工程的童鞋我一开始对这些东西真的没概念啊T_T) 所谓信号,其实就是包含

2014.3.3 图像旋转方法

方法一.利用命令行调用外部程序jpegr.exe 该方法效果最好,弊端是需要外带程序 Command Line JPEG Lossless Rotator allows you to use command line for image transformation. The command format is: <Path to jpegr.exe> jpegr.exe -[r|l|u|v|h] [-s] <filename> ?r - to rotate the image r

css 填坑常用代码分享[居家实用型]

原文地址 http://www.cnblogs.com/jikey/p/4233003.html 以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 一. css 2.x code 1. 文字换行 /*强制不换行*/ white-space:nowrap; /*自动换行*/ word-wrap: break-word; word-break: normal; /*强制英文单词断行*/ word-break:break-all; 2. 两端对齐 text-align:j