"""3、直方图均衡化--直方图、累积分布图"""
img3 = Image.open("car.jpeg")
  #print(type(img3))
  #<class 'PIL.JpegImagePlugin.JpegImageFile'>
img3 = np.array(img3)
  #<class 'numpy.ndarray'>
  #print(type(img3))
  #print(img3.dtype)
  # uint8
plt.hist(img3.ravel())
  #ravel返回一个铺平的数组
plt.show()
  #查看亮度分布,理想的情况是均匀分布
plt.hist(img3.ravel(),bins=255,cumulative=True)
  #参数的含义:分成255份,要画CDF图
plt.show()
  #另一种查看亮度分布的--累积分布函数(CDF)图,理想情况的沿直线增长

  #可以通过直方图均衡,调整图片到最理想的状态
img3_eq = ImageOps.equalize(Image.fromarray(img3))
  #img3是个npdarray,转换为pil才可以放进来
fig = plt.figure(figsize=(16,8))
  #16x8的大小
a = fig.add_subplot(1,2,1)
  #add_subplot的参数:几行,几列,具体地方
imgplot = plt.imshow(img3)
a.set_title("before")

a = fig.add_subplot(1,2,2)
imgplot = plt.imshow(img3_eq)
a.set_title("now")

plt.show()

  #看直方图均衡以后的亮度分布,方法一:
img3_eq = np.array(img3_eq)#注意图片格式转换,hist使pil里的,需要ndarray格式
plt.hist(img3_eq.ravel())
plt.show()
plt.hist(img3_eq.ravel(),bins=255,cumulative=True)
plt.show()
  #或者在一个图里同时显示,步骤是:创建一个坐标系类的背景图,
  #设置要画的具体位置
  #画图:先把三维转化为一维,再画。写标题,ok啦
  #方法二:
fig = plt.figure(figsize=(16,8))

a = fig.add_subplot(1,2,1)
imgplot = plt.hist(img3_eq.ravel())
a.set_title("after")

a = fig.add_subplot(1,2,2)
imgplot = plt.hist(img3_eq.ravel(),bins=255,cumulative=True)
a.set_title("now")
plt.show()
"""3、去噪"""
import skimage

img3_n = skimage.util.random_noise(img3_eq)
  #这是一个数组,给它加上噪声,噪声就是原来绿的地方不那么绿,
  # 原来不太绿的,给他变绿
plt.imshow(img3_n)
plt.show()
"""高斯滤波"""
#周围加权平均,按距离加权,得到中间这个值,百分比之和为1
from scipy.ndimage.filters import gaussian_filter as gauss
from scipy.ndimage.filters import median_filter as med

img3_gauss = gauss(img3_n,sigma=1)#均值取1,越大越模糊
plt.imshow(img3_gauss)
plt.show()

"""中值滤波"""
#取周围像素的中值
img3_med = med(img3_n,size=3)#3X3大小的区域
plt.imshow(img3_med)
plt.show()
"""4、特征提取"""
"""sobel边缘检测"""
#寻找图像上纵横方向变化较大的区域
#步骤:1、彩色转为灰度2、计算横向、纵向梯度3、计算梯度大小4、规范化梯度值0-1之间


def edge_sobel(image):
    from scipy import ndimage
    import skimage.color as sc
    import numpy as np
    image = sc.rgb2gray(image)#1、
    dx = ndimage.sobel(image,1)#2、
    #1是水平方向的梯度
    dy = ndimage.sobel(image,0)#2、
    mag = np.hypot(dx,dy)#3、
    mag *= 255.0/np.amax(mag)
    mag = mag.astype(np.unit8)#再转化成整数
    return mag
if __name__ == '__main__':
    from scipy import ndimage
    img = np.zeros((256,256))#生成黑图
    img[64:-64,64:-64] = 1#取出一块白图
    img[96:-96,0:25] = 1#再取出一块白图

    noise = np.random.randn(img.shape[0],img.shape[1])#给一个尺寸的噪声
    img += noise#原图加上噪声

    img = ndimage.rotate(img,15,mode="constant")#旋转15°
    img = ndimage.gaussian_filter(img,8)#加上高斯噪声
    sx = ndimage.sobel(img,axis = 0, mode = "constant")
    sy = ndimage.sobel(img,axis = 1, mode = "constant")
    sob = np.hypot(sx,sy)

    from skimage.feature import  canny
    canny_edges = canny(img,sigma=5)

    fig = plt.figure(figsize=(14,14))

    ax1 = fig.add_subplot(1,5,1)
    ax1.imshow(img)
    ax1.set_axis_off()
    ax1.set_title("square")

    ax1 = fig.add_subplot(1,5,2)
    ax1.imshow(sx)
    ax1.set_axis_off()
    ax1.set_title("x sobel")

    ax1 = fig.add_subplot(1,5,3)
    ax1.imshow(sy)
    ax1.set_axis_off()
    ax1.set_title("y sobel")

    ax1 = fig.add_subplot(1,5,4)
    ax1.imshow(sob)
    ax1.set_axis_off()
    ax1.set_title("sobel filter")

    ax1 = fig.add_subplot(1,5,5)
    ax1.imshow(canny_edges)
    ax1.set_axis_off()
    ax1.set_title("canny filter")
    plt.show()
"""canny检测    更好"""


"""gauss滤波会把假边界也求出来"""
"""去掉高斯噪声"""
def edge_sobel(image):
    from scipy import ndimage
    import skimage.color as sc
    import numpy as np
    image = sc.rgb2gray(image)#1、
    dx = ndimage.sobel(image,1)#2、
    #1是水平方向的梯度
    dy = ndimage.sobel(image,0)#2、
    mag = np.hypot(dx,dy)#3、
    mag *= 255.0/np.amax(mag)
    mag = mag.astype(np.unit8)#再转化成整数
    return mag
if __name__ == '__main__':
    from scipy import ndimage
    img = np.zeros((256,256))#生成黑图
    img[64:-64,64:-64] = 1#取出一块白图
    img[96:-96,0:25] = 1#再取出一块白图

    noise = np.random.randn(img.shape[0],img.shape[1])#给一个尺寸的噪声
    img += noise#原图加上噪声

    img = ndimage.rotate(img,15,mode="constant")#旋转15°
    #img = ndimage.gaussian_filter(img,8)#加上高斯噪声
    sx = ndimage.sobel(img,axis = 0, mode = "constant")
    sy = ndimage.sobel(img,axis = 1, mode = "constant")
    sob = np.hypot(sx,sy)

    from skimage.feature import  canny
    canny_edges = canny(img,sigma=5)

    fig = plt.figure(figsize=(14,14))

    ax1 = fig.add_subplot(1,5,1)
    ax1.imshow(img)
    ax1.set_axis_off()
    ax1.set_title("square")

    ax1 = fig.add_subplot(1,5,2)
    ax1.imshow(sx)
    ax1.set_axis_off()
    ax1.set_title("x sobel")

    ax1 = fig.add_subplot(1,5,3)
    ax1.imshow(sy)
    ax1.set_axis_off()
    ax1.set_title("y sobel")

    ax1 = fig.add_subplot(1,5,4)
    ax1.imshow(sob)
    ax1.set_axis_off()
    ax1.set_title("sobel filter")

    ax1 = fig.add_subplot(1,5,5)
    ax1.imshow(canny_edges)
    ax1.set_axis_off()
    ax1.set_title("canny filter")
    plt.show()
"""5、Harris Corner Detector哈里斯边角侦测"""
"""检测所有方向上像素变化较大的区域"""

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

filename = "chessboard.jpg"
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)

gray = np.float32(gray)
plt.imshow(gray)
plt.show()

det = cv2.cornerHarris(gray,2,3,0.04)
  #检测边角
det = cv2.dilate(det,None)
  #扩大边角,容易看
img[det>0.01*det.max()] = [0,0,255]
#边角标出来,大于多少的
plt.imshow(img)
plt.show()