视觉图像基础处理

写在前言----

这是我第一次去尝试写自己的博客,想把自己的学习历程好好记录下来,以前学习的时候都没能好好认真的学,代码大部分都是用的同学的,没有自食其力,发现自己只会一些很基本的东西,学习了python近两年,学了人工智能基础,数据结构算法,python基础,模式识别,数据挖掘等课程,但都没能好好有一个记录或者说是一个自己去探索的过程,导致脑袋空空,可以说是会一点皮毛,但不精通,但这并不是我想要的,我想通过自己的努力慢慢把以前落下的重新拾起来,一步一个脚印慢慢积累。

现在是新的一个学期,这是我们第一次的实验课,虽然对于很多人来说可能是很简单,但是对于我来说是一个回顾也同时是一个新探索的过程,我会把自己学习到的东西分享给大家,会去探索,去创新,去创造属于自己的东西


1.均值滤波

1.1 构建添加中文字符函数

1、导入cv2库,用于图像处理。

2、导入numpy库,用于数组计算。

3、导入matplotlib库的pyplot模块,用于绘图。

4、导入math,用于数学计算。

5、导入PIL库的Image、ImageDraw和ImageFont模块。

6、构建图片添加中文字符函数ImgText_CN(),其中的参数为图像矩阵、文字、左上角坐标、颜色和字体大小。

import cv2
import numpy as np
import matplotlib.pyplot as plt
import math
from PIL import Image, ImageDraw, ImageFont
  • 构建图片添加中文字符函数ImgText_CN(),其中的参数为图像矩阵、文字、左上角坐标、颜色和字体大小。

def ImgText_CN(img, text, left, top, textColor=(255, 0, 0), textSize=20):
    if (isinstance(img, np.ndarray)): #判断是否为OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img)
    fontText = ImageFont.truetype(font='simhei.ttf',size=textSize, index=0)
    #font='simhei.ttf'微软雅黑文件
    draw.text((left, top), text, textColor, font=fontText) #写文字
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

1.2 读取图片

使用cv2.imshow()函数展示图像。

使用cv2.waitKey()函数设置等待键盘输入,不输入则无限等待。

使用cv2.destroyAllWindows()函数关闭所有窗口。

# 读取图片
key_img =  cv2.imread(r"C:\Users\11657\Desktop\data\key.jpg")
res1 = ImgText_CN(key_img, '钥匙', 5, 5, textColor=(255, 0, 0), textSize=20) 
#绘制文字
cv2.imshow('key',res1)
cv2.waitKey()
cv2.destroyAllWindows

1.3 均值滤波

OpenCV中提供blur函数来进行图像均值滤波,只取内核区域下所有像素的平均值并替换中心元素,其对应参数如下。

cv2.blur(img, ksize)

img:原图像

ksize:核大小

返回值:图像矩阵

# 均值滤波
img = cv2.blur(key_img, (3, 3)) 
res2 = ImgText_CN(img,'均值滤波', 5, 5, textColor=(255, 0, 0), textSize=20)
cv2.imshow('key',res2)
cv2.waitKey()
cv2.destroyAllWindows()

1.4 中值滤波

OpenCV中提供medianBlur函数来进行图像中值滤波,相当于将方框内的个值进行排序,取中值作为当前值,其对应参数如下。

cv2.medianBlur(img, k)

img:原图像

k:方框的尺寸

返回值:图像矩阵

# 中值滤波
img = cv2.medianBlur(key_img, 5)
res3 = ImgText_CN(img, '中值滤波', 5, 5, textColor=(255, 0, 0), textSize=20)
cv2.imshow('key',res3)
cv2.waitKey()
cv2.destroyAllWindows()

1.5 高斯滤波

OpenCV中提供GaussianBlur函数来进行图像高斯滤波,其对应参数如下。

cv2.GuassianBlur(img, ksize, sigmaX, sigmaY)

img:原图像

ksize:核大小

sigmaX和sigmaY:分别表示X和Y方向的标准偏差,如果仅指定了sigmaX,则sigmaY与sigmaX相同。如果两者都为零,则根据内核大小计算它们。

返回值:图像矩阵

# 高斯滤波
img = cv2.cv2.GaussianBlur(key_img,(5,5), sigmaX=0, sigmaY=0)
res4 = ImgText_CN(img, '高斯滤波', 5, 5, textColor=(255, 0, 0), textSize=20)
cv2.imshow('key',res4)
cv2.waitKey()
cv2.destroyAllWindows()

1.6 双边滤波

OpenCV中提供bilateralFilter函数来进行图像双边滤波,其对应参数如下。

cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)

img:原图像

d:邻域直径

sigmaColor:空间高斯函数标准差,参数越大,临近像素将会在越远的地方越小

sigmaSpace:灰度值相似性高斯函数标准差,参数越大,那些颜色足够相近的的颜色的影响越大

返回值:图像矩阵

# 双边滤波
img = cv2.bilateralFilter(key_img, 5, sigmaColor=5, sigmaSpace=5)
res5 = ImgText_CN(img, '双边滤波', 5, 5, textColor=(255, 0, 0), textSize=20)
cv2.imshow('key',res5)
cv2.waitKey()
cv2.destroyAllWindows()

1.7 不同滤波的边缘检测对比

# 不同滤波的边缘检测对比
img = cv2.Canny(key_img,60,120)
res6 = ImgText_CN(img, '均值边缘检测,中值边缘检测', 5, 5, textColor=(255, 0, 0), textSize=20)
cv2.imshow('key',res6)
cv2.waitKey()
cv2.destroyAllWindows()

个人感觉前面没啥变化,就最后一张变化比较大

2 图像增强

此处的图像处理,这里全部都用的灰度图像处理的也就是说,需要将图像转化为灰度图像

mg = cv2.cvtColor(mg,cv2.COLOR_BGR2GRAY

2.1 灰度直方图

灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。

自定义计算灰度直方图函数calcGrayHist(),设定图像I作为输入参数。

(1)获得图像的长宽。

(2)创建1*256的全零矩阵。

(3)建立双层循环,根据图像个像素点数值,统计不同像素值的出现次数。

(4)将统计结果作为函数返回值。

def calcGrayHist(I): # 计算灰度直方图
    #转化为灰度图
    #img = cv2.cvtColor(I,cv2.COLOR_BGR2GRAY)
    #显示灰度图
    #cv2.imshow('gray_img',img)
    #cv2.waitKey(0)
    #灰度图像矩阵的长,宽
    #rows,cols = img.shape
    rows,cols = I.shape[:2]
    print(I.shape)
    #存储灰度直方图
    grayHist = np.zeros([256],np.uint64)
    for r in range(rows):
        for c in range(cols):
            grayHist[I[r][c]] += 1
    #print(grayHist)
    return grayHist
img = cv2.imread(r"C:\Users\11657\Desktop\data\5.jpg")
cv2.imshow('5',img)
cv2.waitKey()
cv2.destroyAllWindows()
y = calcGrayHist(img)
x = np.arange(256)
# 绘制灰度直方图
plt.plot(x,y,'k-', linewidth=2)
plt.xlabel("gray Label")
plt.ylabel("number of pixels")
plt.show()

2.2 线性变换

1、原图像矩阵乘以2.0,并赋值给变量out。

2、变量out的元素大于255的值截断为255。

3、使用np.around()函数对out进行四舍五入精度计算。

4、使用astype()方法把out类型转为np.uint8。

# 线性变换
imggray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
out = imggray*2
# 进行数据截断,大于255的值截断为255
out[out > 255] =  255
# 数据类型转换
out = np.around(out)
out = np.asarray(out, np.uint8)
cv2.imshow('img',img)
cv2.imshow('out',out)
# 等待键盘输入,不输入则无限等待
# 关闭所有窗口
cv2.waitKey()
cv2.destroyAllWindows()

2.3 直方图正规化

OpenCV中提供normalize函数来进行图像归一化,其对应参数如下。

cv2.normalize(src, dst, alpha, beta, norm_type, dtype, mask)

src:输入数组

dst:与src大小相同的输出数组

alpha:在范围规格化的情况下,规格化到或更低范围边界的标准值

beta:范围归一化情况下的上限范围边界,不用于规范化

norm_type:规范化类型

dtype:如果为负值,则输出数组的类型与src相同;否则,其通道数与src相同

mask:可选操作掩码

# 直方图正规化
out1 = np.zeros([426,640,3],np.uint8)
out1 = cv2.normalize(img,out1,255,0,norm_type=cv2.NORM_MINMAX,dtype=cv2.CV_8U)
out1 = cv2.cvtColor(out1,cv2.COLOR_BGR2GRAY)
cv2.imshow('imggrat',imggray)
cv2.imshow('out1',out1)
# 等待键盘输入,不输入则无限等待
# 关闭所有窗口
cv2.waitKey()
cv2.destroyAllWindows()

2.4 伽马变换

# 伽马变换
# 图像归一化
gamma =  0.4
fi = np.power(imggray/255.0,gamma)
cv2.imshow('imggray',imggray)
cv2.imshow('fi',fi)
# 等待键盘输入,不输入则无限等待
 # 关闭所有窗口
cv2.waitKey()
cv2.destroyAllWindows()

2.5 全局直方图均衡化

OpenCV中提供equalizeHist函数来进行直方图均衡化,其对应参数如下。

cv2.equalizeHist(image,channels,mask,histSize,ranges)

image:待计算直方图的图像,需用[]包裹

channels:指定待计算直方图的图像的哪一通道用来计算直方图,RGB图像可以指定[0,1,2],灰度图像只有[0],需用[]包裹

mask:掩码,可以指定图像的范围,如果是全图,默认为none

hitsize:直方图的灰度级数,例如[0,255]一共256级,故参数为256,需用[]包裹

range:像素值范围,为[0,255]

返回值:直方图矩阵

 全局直方图均衡化
# 如果想要对图片做均衡化,必须将图片转换为灰度图像
dst = cv2.equalizeHist(imggray)
cv2.imshow('imggray',imggray)
cv2.imshow("global equalizeHist", dst)
cv2.waitKey()
cv2.destroyAllWindows()

2.6 限制对比度的自适应直方图均衡化

OpenCV中提供createCLAHA函数来生成自适应均衡化图像,其对应参数如下。

cv2.createCLAHA(clipLimit=5.0, tileGridSize=(8, 8))

clipLimit:颜色对比度的阈值

titleGridSize:进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作

# 限制对比度的自适应直方图均衡化
# 创建CLAHE对象
clahe = cv2.createCLAHE(clipLimit=5.0,tileGridSize=(8, 8))
dst = clahe.apply(gray)#需要先将其转化为灰度图像
cv2.imshow('imggray',imggray)
cv2.imshow('imgclahe',dst)
cv2.waitKey()
cv2.destroyAllWindows()

3 边缘检测

3.1 图片预处理

# 读取图片
image =  cv2.imread(r"C:\Users\11657\Desktop\data\key.jpg")
# 进行高斯模糊操作
image1 = cv2.GaussianBlur(image,(5,5), sigmaX=0, sigmaY=0)
# 进行图片灰度化
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
print(image1.shape)
rett,image1 = cv2.threshold(image1,50,255,cv2.THRESH_BINARY)
# 图像的阈值分割处理,即将图像处理成非黑即白的二值图像
 # 将阈值分割处理后的图片命名为“image1”显示出来
cv2.imshow('image',image)
cv2.imshow('image1',image1)
cv2.waitKey()
cv2.destroyAllWindows()

3.2 二值图像反色处理

print(image1.shape)

# 二值图像的反色处理,将图片像素取反
# 返回图片大小
def access_pixels(image):  # 获取图片高宽通道
    #print(image.shape)
    height = image.shape[0]
    width = image.shape[1]
#    height,width=image.shape
    # 也可以直接写成:
    # height, width, channels = image.shape[:]
    #print("width: %s, height: %s, channels: %s"%(width, height, channels))

    new_image = image.copy()  # 复制image图片
    for row in range(height):
        for col in range(width):
            #for c in range(channels):
#                 pv = new_image[row][ col]
                new_image[row][col] = 255 - new_image[row][col]  # 图像反转
    return new_image
image2=access_pixels(image1)
cv2.imshow('image',image)
cv2.imshow('image2',image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.3 边缘提取

# 边缘提取,使用Canny函数
image3 = cv2.Canny(image2,80,255)
cv2.imshow('image3',image3)
cv2.waitKey()
cv2.destroyAllWindows()

3.4 边缘图像反色处理

#再次对图像进行反色处理使提取的边缘为黑色,其余部分为白色,方法同image2
image3 = access_pixels(image3)
cv2.imshow('image3',image3)
cv2.waitKey()
cv2.destroyAllWindows()

个人觉得本次实验还比较轻松,主要就两个点

第一个就是#font='simhei.ttf'微软雅黑文件,这个文件是可以用自己电脑的字体文件,我之前下载了一个文件导入不了,问了身边的朋友才知道

第二个就是边缘检测应该将其都转换为灰度图像再处理

猜你喜欢

转载自blog.csdn.net/YYANyk/article/details/129383089