Question_21_30

Question:模板

这是一个Question的模块框架

代码:

print("这是一个Question的模块框架")

tips:关于直方图的几个操作解释(仅供参考)

在这里插入图片描述

Question21:直方图归一化(Histogram Normalization)

将直方图所有分量限制在一定范围。虽然有0 ~ 255共256个分级,但是一些图片实际上只分布在一部分上,比如某些图片灰度级只分布在10 ~ 160中,减小了像素中的差异化,使得照片看起来灰蒙蒙的效果。
在这里插入图片描述
用严肃点的话术讲就是动态范围低(最大值:最小值),直方图归一化也叫灰度变换。如下图所示,将绿色是某原图的像素分布,浅绿色是经直方图归一化后的像素分布,可见动态范围变大了,图像中的差异化也也明显了。
在这里插入图片描述
在这里插入图片描述

归一化原理也简单,将10变为0,将160变为255,中间部分等比例扩大即可,公式如下:

  • 将范围从[c,d]变换到[a,b]

    在这里插入图片描述
    如图,这是极端情况,所以通用的变换公式是上方给出的公式,该灰度变换时,按等比例扩展到[a,b],但是起点在a处,所以结果要+a;同时变换后的存在[<a]和[>b]的部分,而我们要求到[a,b],所以[<a]的全部置为a,[>b]的全部置为b

    在这里插入图片描述

代码:

# 
import numpy as np
import cv2
import matplotlib.pyplot as plt


def histNorm(gray,a=0,b=255):
    c=gray.min()
    d=gray.max()
    
    out=gray.copy()
    
    out=(b-a)/(d-c)*(out-c)+a
    out[out<a]=a
    out[out>b]=b
    
    out=out.astype(np.uint8)
    
    return out


img=cv2.imread("../imori_dark.jpg")
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
out =histNorm(gray)
cv2.imshow("",out)
cv2.waitKey(0)

Question22:直方图操作

改变图片的均值和标准差到指定均值和标准差,比如图片的均值和标准差为[m,s],先将其改变为[m0,s0],公式如下:
在这里插入图片描述
在这里插入图片描述

在深度学习中通常出现out=(img-127)/128的操作,实际上对于这是将图片改变到均值为0,标准差为1.

代码:

import numpy as np
import cv2


def getImageMS(img):
    m=np.mean(img)
    s=np.sqrt(np.var(img))
    return m,s


def imageMS(img,m0,s0):
    m,s=getImageMS(img)
    
    out=img.copy()
    
    out=s0/s*(out-m)+m0
    
    out=out.astype(np.uint8)
    
    return out


img=cv2.imread("../imori_dark.jpg")
out=imageMS(img,128,52)
cv2.imshow("img",img)
cv2.imshow("out",out)
cv2.waitKey(0)

以上都只是改变直方图范围,没有改变直方图形状

Question23:直方图均衡

仅仅依靠输入图像的直方图信息,就可以得到一个变换函数,利用该变换函数可以将输入图像达到上述效果,该过程就是直方图均衡化。
也就是前面几种方法都是依靠最大值、最小值、均值和标准差的额外信息完成操作,而直方图均衡仅利用直方图信心完成直方图均衡化。
在这里插入图片描述

公式如下:
在这里插入图片描述

  • Zmax:最大像素值
  • S:像素总数
  • h(i):像素值为0~i的像素总个数

公式表达:像素值为i的像素的新的值为z’

import numpy as  np
import cv2
import matplotlib.pyplot as plt

def hist_equal(img,z_max=255):
    h,w,c=img.shape
    s=h*w*c
    sum_h=0
    out=img.copy()
    for i in range(255):
        ind=np.where(img==i)
        sum_h+=len(img[ind])
        z=z_max/s*sum_h
        out[ind]=z
    out=out.astype(np.uint8)
    return out


img=cv2.imread("../imori.jpg")
out=hist_equal(img)
plt.hist(out.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.show()
cv2.imshow("",out)
cv2.waitKey(0)

Question24:gamma校正

一种非线性校正,转换公式如下:
在这里插入图片描述
I i n I_{in} Iin是图像范围限定在[0,1]之间的,通过控制c和g来进行校正。
使用c=1,g=2.2的gamma校正:
在这里插入图片描述
可以看到像素值是变大了的,同时暗部提亮的值比亮部提亮的值更大。
在这里插入图片描述

代码:

import numpy as np
import cv2
import matplotlib.pyplot as plt

def gammaProcess(img,c=1,g=2.2):
    out=img.copy()
    out=1/c*(img/255)**(1/g)*255
    return out.astype(np.uint8)


img=cv2.imread("../imori_gamma.jpg")

# 展示原图的直方图
plt.hist(img.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.show()

out=gammaProcess(img) # gamma校正

# 展示校正后直方图
plt.hist(out.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.show()

cv2.imshow("",out)
cv2.waitKey(0)

在这里插入图片描述

后面给出代码使用OpenCV提供的API操作,想看作者如何直接操作图像而不利用API请去原项目查看「画像処理100本ノック」中文版本!

Question25:最邻近插值

这是图像方法的算法,关于更多插值放大请移步:图像方法之内插法
opencv中关于图像尺寸操作的方法是:
cv2.resize(img,dsize,fx,fy,interpolation)

  • dsize:将图像缩放到什么尺寸,比如(500,500)即将img缩放到(500,500)
  • fx和fy:行和列的缩放比例因子,比如fx=2,fy=2即将img长宽各放大2倍
  • interpolation:插值方法,效果越好,速度越慢,可选如下:
interpolation描述
cv2.INTER_NEAREST最近邻插值
cv2.INTER_LINEAR双线性插值(默认)
cv2.INTER_CUBIC双三次插值
cv2.INTER_AREA使用像素区域关系重新采样(推荐)

在这里插入图片描述

# 采用最邻近插值法,将图片img缩放大长和宽的0.7倍
img_small=cv2.resize(img,None,fx=0.7,fy=0.7,interpolation=cv2.INTER_NEAREST)

# 采用最邻近插值法,直接缩放到(256,256)
img_256=cv2.resize(img,(256,256),interpolation=cv2.INTER_NEAREST)

Question26:双线性插值

双线性插值其实就是根据位置所在比例来估计像素值,比最邻近插值更加有道理一点,当然计算量更大,效果更好。
在这里插入图片描述

代码:

import cv2

img=cv2.imread("../imori.jpg")
# 将img放大2倍,插值方法为双线性
out=cv2.resize(img,dsize=None,fx=2,fy=2,interpolation=cv2.INTER_LINEAR)
cv2.imshow("",out)
cv2.waitKey(0)

Question27:双三次插值

速度更慢,效果更好(画质有提升,但是不太明显,放大倍数越大越明显)
在这里插入图片描述

代码:

import cv2

img=cv2.imread("../imori.jpg")
# 将img放大3倍,插值方法为双线性
out=cv2.resize(img,dsize=None,fx=3,fy=3,interpolation=cv2.INTER_LINEAR)
# 将img放大3倍,插值方法为双三次
out2=cv2.resize(img,dsize=None,fx=3,fy=3,interpolation=cv2.INTER_CUBIC)

# 展示双线性和双三次放大的图像
cv2.imshow("INTER_LINEAR",out)
cv2.imshow("INTER_CUBIC",out2)

cv2.waitKey(0)

Question28:仿射变换–平移

利用仿射变换让图像在x方向上+30,在y方向上-30吧
什么是仿射变换
如何利用利用仿射变换让图像在x方向上+30,在y方向上-30?看上方链接的栗子5-1

代码:

# 定义原图中三个点pts1
pts1=np.float32(([0,0],[0,127],[127,127]))

# 定义结果图中三个点pts2
pts2=np.float32(([30,0],[30,97],[127,97]))

# 利用这三对点,求出变换矩阵M
M=cv2.getAffineTransform(pts1,pts2)

# 再利用变换矩阵对原图所有像素点进行变换
# 并指定了输出图像的shape和原图shape一样
res=cv2.warpAffine(img,M,dsize=img.shape[0:2])

cv2.imshow("",res)
cv2.waitKey(0)

Question29:仿射变换–放大缩小

在这里插入图片描述
见本文栗子5-2

Question30:仿射变换-旋转

使用仿射变换,使图像逆时针旋转30°
我们知道通过仿射矩阵可以使图像进行仿射变换效果,上述是通过3组对应点来求得变换矩阵,实际上我们可以直接确定变换矩阵:
在这里插入图片描述

  • A:旋转角度
  • t:平移距离

这在文章图像仿射变换第4小节列举过常用变换矩阵。
通过角度我们能够计算出矩阵M:
在这里插入图片描述
效果(旋转30°,不进行偏移):

在这里插入图片描述
效果(旋转30°,横轴左偏移20,纵轴下偏移20):
在这里插入图片描述

代码:

import numpy as np
import cv2

img=cv2.imread("../imori.jpg")

tx=-20 # 控制横轴偏移
ty=20 # 控制纵轴偏移
A=-30 # 旋转角度
M=np.array([[np.cos(A*np.pi/180),-np.sin(A*np.pi/180),tx],[np.sin(A*np.pi/180),np.cos(A*np.pi/180),ty]])

res=cv2.warpAffine(img,M,dsize=img.shape[0:2])

res=res.astype(np.uint8)

cv2.imshow("",res)
cv2.waitKey(0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值