专业的编程技术博客社区

网站首页 > 博客文章 正文

Python-OpenCV 6. 图片灰度化(opencv图像灰度化)

baijin 2024-08-31 16:15:36 博客文章 6 ℃ 0 评论

一、介绍

大部分的彩色图像都是采用RGB颜色模式,处理图像的时候,要分别对RGB三种分量进行处理,实际上RGB并不能反映图像的形态特征,只是从光学的原理上进行颜色的调配。
现在有很多其他的颜色模式,例如HSI模式,HSI是由色调,饱和度,亮度三个分量来表示颜色。HSI比RGB更符合人的视觉特性。

但是HSI也是三通道,真正反映图像特征的变量是I,其他都是色彩的反映。

所以我们经常要把图像弄成8位的灰度值图像直接进行处理,可以通过直方图,灰度变化,还有正交变换之类的进行处理。甚至经常把图像分割之后变成二值图像处理。

灰度化,在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。

一般有分量法、最大值法、平均值法、加权平均法四种方法对彩色图像进行灰度化。

1. 分量法

将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。

f1(i,j)=R(i,j)f2(i,j)=G(i,j)f3(i,j)=B(i,j)

其中fk(i,j)(k=1,2,3)为转换后的灰度图像在(i,j)处的灰度值。

2. 最大值法

将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。

f(i,j)=max(R(i,j),G(i,j),B(i,j))

3. 平均值法

将彩色图像中的三分量亮度求平均得到一个灰度值。

f(i,j)=(R(i,j)+G(i,j)+B(i,j)) /3

4.加权平均法

根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。

f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j)

(摘自百度百科)

灰度化与二值化不同,二值化是每个像素值设置为0或255.

二、使用OpenCV 灰度化

# -*- coding: utf-8 -*-
import cv2

fn = "test.jpg"
if __name__ == '__main__':
 print('loading %s' % fn)
 img = cv2.imread(fn)
 sp = img.shape
 print(sp)

 # 获取图像大小
 sz1 = sp[0]
 sz2 = sp[1]
 print('width:%d\nheight:%d' % (sz2, sz1))

 # 复制并转换为灰度化图像并显示
 myimg1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
 cv2.imshow('myimg1',myimg1)
 cv2.waitKey()
 cv2.destroyAllWindows()

三、使用PIL库实现灰度化

# -*- coding: utf-8 -*-
from PIL import Image
import matplotlib.pyplot as plt
fn = "test.jpg"
def showimg(img, isgray=False):
 plt.axis("off")
 if isgray == True:
 plt.imshow(img, cmap='gray')
 else:
 plt.imshow(img)
 plt.show()
if __name__ == '__main__':
 image = Image.open(fn)
 im_gray = image.convert('L')
 showimg(im_gray, True)

三、使用numpy运算实现灰度化

1. 使用浮点算法 Gray=R0.3+G0.59+B*0.11

# -*- coding: utf-8 -*-
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
fn = "test.jpg"
def showimg(img, isgray=False):
 plt.axis("off")
 if isgray:
 plt.imshow(img, cmap='gray')
 else:
 plt.imshow(img)
 plt.show()
if __name__ == '__main__':
 image = Image.open(fn)
 im = np.array(image)
 im[:, :, 0] = im[:, :, 0] * 0.3
 im[:, :, 1] = im[:, :, 1] * 0.59
 im[:, :, 2] = im[:, :, 2] * 0.11
 im = np.sum(im, axis=2)
 
 showimg(Image.fromarray(im), True)

2. 使用整数算法 Gray=(R30+G59+B*11)/100

# -*- coding: utf-8 -*-

from PIL import Image

import matplotlib.pyplot as plt

import numpy as np

fn = "test.jpg"

def showimg(img, isgray=False):

plt.axis("off")

if isgray:

plt.imshow(img, cmap='gray')

else:

plt.imshow(img)

plt.show()

if __name__ == '__main__':

image = Image.open(fn)

im = np.array(image, dtype=np.float32)

im[..., 0] = im[..., 0] * 30.0

im[..., 1] = im[..., 1] * 59.0

im[..., 2] = im[..., 2] * 11.0

im = np.sum(im, axis=2)

im[..., :] = im[..., :] / 100.0

showimg(Image.fromarray(im), True)

3. 使用平均值法

im = np.array(image, dtype=np.float32)
im = np.sum(im, axis=2)
im[...,:] = im[...,:]/3.0

4. 使用移位法

# -*- coding: utf-8 -*-

from PIL import Image

import matplotlib.pyplot as plt

import numpy as np

fn = "test.jpg"

def showimg(img, isgray=False):

plt.axis("off")

if isgray:

plt.imshow(img, cmap='gray')

else:

plt.imshow(img)

plt.show()

if __name__ == '__main__':

image = Image.open(fn)

im = np.array(image, dtype=np.int32)

im[..., 0] = im[..., 0] * 28.0

im[..., 1] = im[..., 1] * 151.0

im[..., 2] = im[..., 2] * 76.0

im = np.sum(im, axis=2)

arr = [np.right_shift(y.item(), 8) for x in im for y in x]

arr = np.array(arr)

arr.resize(im.shape)

showimg(Image.fromarray(arr), True)

5. 单通道法(只取绿色通道)

# -*- coding: utf-8 -*-
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
fn = "test.jpg"
def showimg(img, isgray=False):
 plt.axis("off")
 if isgray:
 plt.imshow(img, cmap='gray')
 else:
 plt.imshow(img)
 plt.show()
if __name__ == '__main__':
 image = Image.open(fn)
 im = np.array(image, dtype=np.int32)
 im[..., 0] = 0
 im[..., 2] = 0
 im = np.sum(im, axis=2)
 showimg(Image.fromarray(im), True)

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表