图像灰度化与二值化

图像灰度化

什么是图像灰度化?

图像灰度化并不是将单纯的图像变成灰色,而是将图片的BGR各通道以某种规律综合起来,使图片显示位灰色。
规律如下:
图像灰度化与二值化

手动实现灰度化

首先我们采用手动灰度化的方式:
其思想就是:
先创建一个跟原来长宽一样的空白图片,然后将原图片中图片各个像素按照下面公式填入图片中,实现灰度化。
图像灰度化与二值化

import cv2
import numpy as np
from skimage.color import rgb2gray
from PIL import Image
import matplotlib.pyplot as plt


img = cv2.imread("lenna.png")   #opencv读取图像
#img = plt.imread("lenna.png")  #matlab读取图像
h,w = img.shape[:2] #读出图像的长宽
img_gray = np.zeros([h,w],img.dtype)    #创建一个与当前图像相同长宽的单通道图片
for i in range(h):
    for j in range(w):
        m = img[i,j]
        img_gray[i,j] = int(m[0]*0.11+m[1]*0.59+m[2]*0.3)   #将CV读取的BGR转化为gray值给新图像

print(img_gray)
cv2.imshow('gray picture ',img_gray)    #cv展示灰色图像
cv2.waitKey (0) #如果不写等待时间,图像会一闪而过

skimage实现图像灰度化

img = cv2.imread("lenna.png")
img_gray = rgb2gray(img)
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)

opencv实现图像灰度化

img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#用opencv输出
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)

#用plt输出:这里要注意,cmap为颜色图谱,默认为RGB(A)颜色空间,也可以指定,gray是灰度图,若cmap为其他会造成色差
plt.imshow(img_gray,cmap="gray")
plt.show()

图像二值化

什么是图像二值化?

所谓图像二值化,就是将图像中像素点的值取其中间值,若大于中间值,则将该像素点的值设为最大值,若小于中间值,则把该像素点设为最小值。使整个图片最后只存在两个值:最大值和最小值。

手动实现二值化

img = plt.imread("lenna.png")
img_gray = rgb2gray(img)	#这里还是要先灰度化
rows, cols = img_gray.shape
for i in range(rows):
    for j in range(cols):
        if (img_gray[i, j] <= 0.5):
            img_gray[i, j] = 0
        else:
            img_gray[i, j] = 1

plt.imshow(img_gray,cmap="gray")
plt.show()

numpy实现图像二值化

img = plt.imread("lenna.png")
img_gray = rgb2gray(img)#这里还是要先灰度化

img_binary = np.where(img_gray >= 0.5, 1, 0)
plt.imshow(img_binary,cmap="gray")
plt.show()

opencv实现图像二值化

img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#这里还是要先灰度化

cv2.threshold(img_gray,127,255,0,img_gray)
cv2.imshow('img_binary',img_gray)
cv2.waitKey(0)

全部代码与实现结果:

全部代码:

import cv2
import numpy as np
from skimage.color import rgb2gray
from PIL import Image
import matplotlib.pyplot as plt

"""
手动实现图像灰度化
"""

img = cv2.imread("lenna.png")   #opencv读取图像
#img = plt.imread("lenna.png")  #matlab读取图像
h,w = img.shape[:2] #读出图像的长宽
img_gray = np.zeros([h,w],img.dtype)    #创建一个与当前图像相同长宽的单通道图片
for i in range(h):
    for j in range(w):
        m = img[i,j]
        img_gray[i,j] = int(m[0]*0.11+m[1]*0.59+m[2]*0.3)   #将CV读取的BGR转化为gray值给新图像,注意:这个公式是内定的

print(img_gray)
cv2.imshow('gray picture ',img_gray)    #cv展示灰色图像
cv2.waitKey (0) #如果不写等待时间,图像会一闪而过

"""
skimage实现图像灰度化
"""

img = cv2.imread("lenna.png")
img_gray = rgb2gray(img)
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)

"""
opencv实现图像灰度化
"""

img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#用opencv输出
cv2.imshow('gray picture ',img_gray)
cv2.waitKey (0)

plt.imshow(img_gray,cmap="gray")
plt.show()

"""
手动图像二值化
"""
img = plt.imread("lenna.png")
img_gray = rgb2gray(img)
rows, cols = img_gray.shape
for i in range(rows):
    for j in range(cols):
        if (img_gray[i, j] <= 0.5):
            img_gray[i, j] = 0
        else:
            img_gray[i, j] = 1

plt.imshow(img_gray,cmap="gray")
plt.show()

"""
numpy实现图像二值化
"""
img = plt.imread("lenna.png")
img_gray = rgb2gray(img)
img_binary = np.where(img_gray >= 0.5, 1, 0)
plt.imshow(img_binary,cmap="gray")
plt.show()

"""
opencv实现图像二值化
"""

img = cv2.imread("lenna.png")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.threshold(img_gray,127,255,0,img_gray)
cv2.imshow('img_binary',img_gray)
cv2.waitKey(0)

实现结果:

原图:
图像灰度化与二值化
灰度化:
图像灰度化与二值化
二值化:
图像灰度化与二值化

思考与问题:

1.二值化中plt与cv阈值不同问题:

在plt读取图像之后,图像的每一个像素值都在[0,1]之间,在之后的cv2读取的图像,每一个像素值在[0,255]之间,所以在二值化时,plt是阈值为0.5,像素值分成0或1,而cv2中阈值是127,像素值分为0或255。

2.plt与cv交叉读取数据会出现图像失真问题:

因为 opencv 的接口使用BGR模式,而 matplotlib.pyplot 接口使用的是RGB模式
解决方法是:
在cv输入图像后把通道顺序变换一下,就在cv2.imread输入后面添加

b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])

3.在灰度化和二值化图像用plt输出的时候必须添加cmap = ‘gray’,如果图像会失真

用plt输出中cmap为颜色图谱,默认为RGB(A)颜色空间,也可以指定,gray是灰度图,若cmap为其他会造成色差

4.CV或者plt打印图像时很快消失:

无论谁cv输出还是plt输出的最后的结尾都需要加上cv.waitkey(0)或者plt.show()不然输出图像转瞬即逝,很快就消失了,不能长时间停留。

5.PLT和openCV读取和输出方法:

PLT:

#输入
img = plt.imread("lenna.png")
#输出
plt.imshow(img,cmap="gray")
plt.show()

CV:

#输入
img = cv2.imread("lenna.png")
#输出
cv2.imshow('img',img_gray)
cv2.waitKey(0)
上一篇:【车辆计数】基于光流法实现车辆检测计数matlab 源码


下一篇:image2graph2pgdb