numpy 旋转 图像增强_仅使用numpy通过任意角度剪切变换旋转图像-程序员宅基地

技术标签: python  计算机视觉  人工智能  numpy  opencv  

numpy 旋转 图像增强

These days, we are spoiled with high end libraries. When It comes to Image Processing and advanced libraries such as OpenCV Rotating Image may sound like a very easy task using inbuilt functions.I am not telling you to code everything from scratch, However, an understanding about how things work will make you a better programmer. So let’s get started.

牛逼 HESE日子里,我们都被宠坏了与高端库。 对于图像处理和高级库(例如OpenCV Rotating Image)来说,使用内置函数听起来很容易。我并不是在告诉您从头开始编写所有代码,但是,了解如何工作将使您成为一个更好的程序员。 因此,让我们开始吧。

位图 (BITMAPS)

A typical computer image these days uses 24 bits to represent the color of each pixel. Eight bits are used to store the intensity of the red part of a pixel (00000000 through 11111111), giving 256 distinct values. Eight bits are used to store the green component, and eight bits are used to store the blue component.

如今,典型的计算机图像使用24位来表示每个像素的颜色。 八位用于存储像素红色部分的强度( 0000000011111111 ),给出256个不同的值。 八位用于存储绿色分量,八位用于存储蓝色分量。

Image for post

Each pixel has a coordinate pair (x,y) describing its position on two orthogonal axes from defined origin O.It is around this origin we are going to rotate this image.What we need to do is take the RGB values at every (x,y) location, rotate it as needed, and then write these values in the new location, considering (x,y) with respect to the origin we assumed.The new location is obtained by using the transformation matrix.

每个像素都有一个坐标对(x,y),描述了它在从定义的原点O开始的两个正交轴上的位置。围绕该原点,我们将旋转该图像。我们需要做的是在每个(x ,y)位置,根据需要旋转它,然后将这些值写入新位置,并考虑相对于我们假设的原点的(x,y)。使用转换矩阵获得新位置。

Image for post

When image will be rotated ,the dimension of the frame containing it will change so to find the new dimensions we use this formula,

当图像旋转时,包含图像的框架的尺寸将发生变化,因此要使用此公式查找新的尺寸,

new_width=|old_width×cosθ|+|old_height×sinθ|

new_width = | old_width×cosθ | + | old_height×sinθ |

new_height=|old_height×cosθ|+ |old_row×sinθ|

new_height = | old_height×cosθ | + | old_row×sinθ |

now let’s code it

现在让我们编码

Image for post
mage obtained by Rotation Matrix 通过旋转矩阵获得的图像

ALIASING

混叠

Image for post

So our resultant image is rotated by 15 degrees ,so it really worked,but what are those black dots?This is a problem called aliasing.Multiplying by sines and cosines on the integer coordinates of the source image gives real number results, and these have to be rounded back to integers again to be plotted. Sometimes this number rounding means the same destination location is addressed more than once, and sometimes certain pixels are missed completely. When the pixels are missed, the background shows through. This is why there are holes.The aliasing problem gets worse when angles are closesr to the diagonals. Here are a few examples of images at different rotations:

因此我们将结果图像旋转了15度,它确实起作用了,但是那些黑点是什么呢?这是一个别名问题。在源图像的整数坐标上乘正弦余弦得出实数结果,这些结果再次四舍五入为整数以进行绘制。 有时,此数字舍入意味着对同一目标位置的寻址不止一次,有时某些像素完全丢失。 当像素丢失时,背景将显示出来。 这就是为什么有Kong的原因。当角度接近对角线时,混叠问题会变得更糟。 以下是一些不同旋转图像的示例:

What can we do about this? There are a variety of solutions. One of them is to oversample the source image. We can pretend that each of the original source pixels is really a grid of n x n smaller pixels (all of the same color), and calculate the destination coordinates of each of these subpixels and plot these

我们该怎么办? 有多种解决方案。 其中之一是对源图像进行过采样。 我们可以假设每个原始源像素实际上是n × n个较小像素(都具有相同颜色)的网格,然后计算这些子像素中每个像素的目标坐标并绘制这些像素

A more refined way is called Area Mapping. For this, you invert the problem, and for each destination pixel, you find which four partial source pixels that it was created from. The color for the destination is calculated by the area-weighted average of the four source pixels (The source pixels that contribute more to the destination pixel have a greater influence on its color). This algorithm not only ensures that there are no gaps in the destination, but also appropriately averages the colors (ensuring both a smoother image and also keeping the average brightness of the rotated image constant).

一种更完善的方法称为区域映射 。 为此,您可以将问题反转,并为每个目标像素找到创建该像素的四个部分源像素。 通过四个源像素的面积加权平均值计算出目标的颜色(对目标像素贡献更大的源像素对其颜色的影响更大)。 该算法不仅确保目标上没有间隙,而且可以适当地平均颜色(既确保图像更平滑,又保持旋转图像的平均亮度恒定)。

However, there is a more elegant method, and this is the method that was used many years ago when computing power (and memory) were at a premium and every processor cycle worth its weight in gold. It is called the three shear rotation method.

但是,还有一种更优雅的方法,这是很多年前使用的方法,当时计算能力(和内存)非常宝贵,并且每个处理器周期都具有其价值。 称为三剪切旋转法。

三剪 (THREE SHEARS)

These method works by expanding 2D rotation matrix into three different matrices.

这些方法通过将2D旋转矩阵扩展为三个不同的矩阵来工作。

Image for post

There are some interesting properties of this matrix:-

这个矩阵有一些有趣的特性:

  1. The three matrices are all shear matrices

    这三个矩阵都是剪切矩阵
  2. The first and the last matrices are the same

    第一个和最后一个矩阵相同
  3. The determinant of each matrix is same (each stage is conformal and keeps the area the same).

    每个矩阵的行列式相同(每个阶段都是保形的,并且使面积相同)。
  4. 4. As the shear happens in just one plane at time, and each stage is conformal in area, no aliasing gaps appear in any stage.

    4.由于剪切力一次仅在一个平面上发生,并且每个阶段的面积都是共形的,因此在任何阶段都不会出现锯齿间隙。

note: Shear matrix shown above rotates in clockwise direction so we need to take angle in negative values to assess for that.

注意:上面显示的剪切矩阵沿顺时针方向旋转,因此我们需要将角度取负值进行评估。

So let’s code the shear transformation

所以让我们编写剪切转换的代码

import numpy as np
from PIL import Image
import math




def shear(angle,x,y):
    '''
    |1  -tan(/2) |  |1        0|  |1  -tan(/2) | 
    |0      1     |  |sin()   1|  |0      1     |

    '''
    # shear 1
    tangent=math.tan(angle/2)
    new_x=round(x-y*tangent)
    new_y=y
    
    #shear 2
    new_y=round(new_x*math.sin(angle)+new_y)      #since there is no change in new_x according to the shear matrix


    #shear 3
    new_x=round(new_x-new_y*tangent)              #since there is no change in new_y according to the shear matrix
    


    return new_y,new_x








image = np.array(Image.open("test.png"))             # Load the image
angle=-int(input("Enter the angle :- "))                # Ask the user to enter the angle of rotation


# Define the most occuring variables
angle=math.radians(angle)                               #converting degrees to radians
cosine=math.cos(angle)
sine=math.sin(angle)


height=image.shape[0]                                   #define the height of the image
width=image.shape[1]                                    #define the width of the image


# Define the height and width of the new image that is to be formed
new_height  = round(abs(image.shape[0]*cosine)+abs(image.shape[1]*sine))+1
new_width  = round(abs(image.shape[1]*cosine)+abs(image.shape[0]*sine))+1


# define another image variable of dimensions of new_height and new _column filled with zeros
output=np.zeros((new_height,new_width,image.shape[2]))
image_copy=output.copy()




# Find the centre of the image about which we have to rotate the image
original_centre_height   = round(((image.shape[0]+1)/2)-1)    #with respect to the original image
original_centre_width    = round(((image.shape[1]+1)/2)-1)    #with respect to the original image


# Find the centre of the new image that will be obtained
new_centre_height= round(((new_height+1)/2)-1)        #with respect to the new image
new_centre_width= round(((new_width+1)/2)-1)          #with respect to the new image




for i in range(height):
    for j in range(width):
        #co-ordinates of pixel with respect to the centre of original image
        y=image.shape[0]-1-i-original_centre_height                   
        x=image.shape[1]-1-j-original_centre_width 


        #Applying shear Transformation                     
        new_y,new_x=shear(angle,x,y)


        '''since image will be rotated the centre will change too, 
            so to adust to that we will need to change new_x and new_y with respect to the new centre'''
        new_y=new_centre_height-new_y
        new_x=new_centre_width-new_x




        # adding if check to prevent any errors in the processing
        if 0 <= new_x < new_width and 0 <= new_y < new_height and new_x>=0 and new_y>=0:
            output[new_y,new_x,:]=image[i,j,:]                          #writing the pixels to the new destination in the output image




pil_img=Image.fromarray((output).astype(np.uint8))                       # converting array to image
pil_img.save("rotated_image.png")                                                 # saving the image
Image for post

In the first shear operation, raster columns are simply shifted up and down relative to each other. The shearing is symmetric around the center of the image. It’s analogous to shearing a deck of playing cards.

在第一个剪切操作中,光栅列只是简单地相对于彼此上下移动。 剪切在图像中心周围对称。 这类似于剪切一副扑克牌。

The second shear operation does a similar thing on the previous image, but this time does the shearing left to right.

第二次剪切操作在上一张图像上执行类似的操作,但是这次从左到右进行剪切。

The final shear is the same as the first operation; this time applied to the intermediate image.

最终剪切力与第一次操作相同; 这次应用于中间图像。

No gaps! How elegant is that? We just rotated an image an arbitrary amount (smoothly) using three shear operations!

没有差距! 那有多优雅? 我们仅使用三个剪切操作就将图像旋转了任意数量(平滑)!

In times-past, when floating point and trig calculations were expensive, these properties were very important. Because only one plane was being modified at once, no additional memory was needed as the code could simple walk down the raster line making the changes it needed. Pretty cool.

过去,当浮点和触发器的计算非常昂贵时,这些属性非常重要。 由于一次只能修改一个平面,因此不需要额外的内存,因为代码可以简单地沿着栅格线移动,进行所需的更改。 很酷

翻译自: https://medium.com/@gautamnagrawal/rotating-image-by-any-angle-shear-transformation-using-only-numpy-d28d16eb5076

numpy 旋转 图像增强

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_26723981/article/details/108498293

智能推荐

探访“全甲格斗”圈 文职员工穿上盔甲就成场上最凶猛的人-程序员宅基地

文章浏览阅读1.3k次。法制晚报2018-12-2813:16:39穿着古代武士的盔甲,手持青龙偃月刀,征服欧洲的大陆,已经不仅仅是停留在网络游戏《全面战争》的3D画面中。现实里,有人正在为实现这样的“梦想”而努力。现场12月22日晚间,在小红门附近的一家练舞场内,为春节彩排节目的舞狮队刚刚离开,几个人高马大的中年人便亢奋地涌进场内。他们打开上百斤的行李箱,从里面一片片的金属铠甲和兵器,这不是要为春节晚会的节目彩排,而是..._虎贲骑士团 银月

LeetCode-2. 两数相加-程序员宅基地

文章浏览阅读49次。这里写目录标题2. 两数相加2. 两数相加给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。示例 1:输入:l1 = [2,4,3], l2 = [5,6,4]输出:[7,0,8]解释:342 + 465 = 807.示例 2:输入:l1 = [0], l2 = [0]输出:[0]示例 3:输入:l1 =

求职季,前端面试送给你|掘金技术征文-程序员宅基地

文章浏览阅读146次。前言最近好多小伙伴都跳槽去找工作,我只能在心里默默的支持他们能找到一份好的工作,这份前端面试大全送给我的小伙伴们,主要说的是前端一些常用的一些知识,说的不对的地方请小伙伴们即使指正出来,自己同时也回顾下这些知识。主要分以下几个方边来说:css和htmljavascriptvue微信小程序css和html1.Doctype作用?标准模式和兼容模式区别。声明在HTML文档第一行,告诉浏览器用什么文档标..._前端面试给你场景实现功能

Flashback database--闪回数据库-程序员宅基地

文章浏览阅读708次。Flashback Database提供数据库级别的恢复,可以将整个数据库恢复到指定的时间点。Flashback Database引入Flashback Logs,日志记录操作执行前要修改的数据,即数据块的前映象。这些信息被写入专用存储区Flash Recovery Area一、实现Flashback Database的必要条件:*数据库必须处于归档模式*数据库必须指定了Flash

长短期记忆网络(Long Short-Term Memory,LSTM)及其变体双向LSTM和GRU-程序员宅基地

文章浏览阅读5.4w次,点赞45次,收藏219次。LSTM(Long Short-Term Memory)长短期记忆网络,是一种时间递归神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM是解决循环神经网络RNN结构中存在的“梯度消失”问题而提出的,是一种特殊的循环神经网络。_long short-term memory

flashback database 方法-程序员宅基地

文章浏览阅读57次。SQL*Plus: Release 10.2.0.4.0 - Production on Sat Jan 23 23:30:17 2010Copyright (c) 1982, 2007, Oracle. All..._flashback database to timestamp to_timestamp('frombyte 2007-2-12 12:00:0

随便推点

Cause: com.mysql.jdbc.PacketTooBigException_error updating database. cause: com.mysql.jdbc.pac-程序员宅基地

文章浏览阅读8.5k次,点赞5次,收藏9次。今天在做批量上传的时候爆了一个错误,之前都没有遇到过;Error updating database. Cause: com.mysql.jdbc.PacketTooBigException:Packet for query is too large (9270713 > 4194304). You can change this value on the server by _error updating database. cause: com.mysql.jdbc.packettoobigexception: packet

膨胀卷积神经网络_用膨胀的卷积神经网络生成钢琴音乐-程序员宅基地

文章浏览阅读2.7k次。膨胀卷积神经网络 介绍 (Introduction)Fully convolutional neural networks consisting of dilated 1D convolutions are straightforward to construct, easy to train, and can generate realistic piano music, such as th..._膨胀门卷积神经网络

mysql一键执行脚本 超方便!!!_数据库脚本一件执行-程序员宅基地

文章浏览阅读2.5k次,点赞3次,收藏10次。mysql一键执行脚本mysql一键执行脚本mysql一键执行脚本在初始虚拟机上,直接复制就ok了#!/bin/bashecho "-------编译安装mysqld 服务--------"#将安装mysql 所需软件包传到/opt目录下#mysql-5.7.17.tar.gz#boost_1_59_0.tar.gz #支持c++的运行库echo "安装环境依赖包"yum -y install gcc gcc-c++ ncurses ncurses-devel bison cm_数据库脚本一件执行

数据解析(网络返回)-程序员宅基地

文章浏览阅读345次。我们从服务器得到的数据有时候不可能一开始就是字典\数组数据,有时候需要我们对得到的数据进行转换1、当服务器返回的是的data数据类型,我们可能需要转换成字典或数组才能使用,使用下方法转换: {    // Data 转 字典 ,其中responseObject为返回的data数据 NSDictionary *resultDictionary = [N..._网络返回

unity光源自带的Halo效果_unity halo-程序员宅基地

文章浏览阅读2.7k次,点赞3次,收藏3次。之前看过一个用来实现光晕效果的shader,但是这个shader似乎只适用于球状物,对于非球状物就不是很友好。效果如图1、图2所示。今天发现unity中的光源居然自带halo效果(版本是2019.1.4f1),在inspector面板勾选Draw Halo即可,用它就可以来模拟光晕,效果还不错。如图3所示。搭配standard shader中的emission,感觉贼好用。(如图4的不明..._unity halo

Java图片和二进制互转-程序员宅基地

文章浏览阅读165次。Java图片和二进制互转,可以是jpg,png,gif格式package com.webkfa.test;/** * * @author songlei */import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArray..._php读取的图片字符串和java读取的图片二进制字符串不一致

推荐文章

热门文章

相关标签