OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)

2023-11-07

 

人工智能学习离不开实践的验证,推荐大家可以多在FlyAI-AI竞赛服务平台多参加训练和竞赛,以此来提升自己的能力。FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台。每周免费提供项目开源算法样例,支持算法能力变现以及快速的迭代算法模型。

如果需要处理的原图及代码,请移步小编的GitHub地址

  传送门:请点击我

  如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice

  下面主要学习图像灰度化的知识,结合OpenCV调用 cv2.cvtColor()函数实现图像灰度化,使用像素处理方法对图像进行灰度化处理。

1.  图像灰度化

1.1 图像灰度化的目的

  将彩色图像转化为灰度图像的过程是图像的灰度化过程。彩色图像中的每个像素的颜色由 R, G, B三个分量决定,而每个分量中可以取值 0~255,这样一个像素点可以有 1600多万(255*255*255=16581375)的颜色的变化范围。而灰度图像是 R,G,B三个分量相同的一种特殊的彩色图像,其中一个像素点的变换范围为 256 种,所以在数字图像处理中一般将各种格式的图像转换为灰度图像以使后续的图像计算量少一些。灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和高亮等级的分布和特征。

1.2  图像灰度化原理

  图像灰度化是将一幅彩色图像转换为灰度化图像的过程。彩色图像通常包括R、G、B三个分量,分别显示出红绿蓝等各种颜色,灰度化就是使彩色图像的R、G、B三个分量相等的过程。灰度图像中每个像素仅具有一种样本颜色,其灰度是位于黑色与白色之间的多级色彩深度,灰度值大的像素点比较亮,反之比较暗,像素值最大为255(表示白色),像素值最小为0(表示黑色)。

  图像灰度化核心思想是 R = G = B ,这个值也叫灰度值。

  假设某点的颜色由RGB(R,G,B)组成,常见灰度处理算法如下表所示(盗图:https://blog.csdn.net/Eastmount/article/details/88785768)

   上表中Gray表示灰度处理之后的颜色,然后将原始RGB(R,G,B)颜色均匀地替换成新颜色RGB(Gray,Gray,Gray),从而将彩色图片转化为灰度图像。

  一种常见的方法是加权平均灰度处理,这种效果是最好的。是将RGB三个分量求和再取平均值,但更为准确的方法是设置不同的权重,将RGB分量按不同的比例进行灰度划分。比如人类的眼睛感官蓝色的敏感度最低,敏感最高的是绿色,因此将RGB按照0.299、0.587、0.114比例加权平均能得到较合理的灰度图像,如公式所示:

1.3  图像灰度化的三种方法

1.3.1  OpenCV直接灰度化

  下面的这种方法,在读取图片的时候,直接将图片转化为灰度化:

1

2

3

import cv2

 

img = cv2.imread(photo_file, cv2.IMREAD_GRAYSCALE)

  得到的img是一个函数。

1.3.2   OpenCV先读取再灰度化

  下面的方法,先读取图片,然后再转化为灰度图。

1

2

3

4

5

import  cv2

 

img = cv2.imread(photo_file)

# Y = 0.299R + 0.587G + 0.114B

grey_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

  

1.3.3  使用PIL库中的Image模块

  首先读取图片,然后灰度化,最后转化为数组

1

2

3

4

5

6

7

8

9

import numpy as np

form PIL import Image

 

# 使用PIL库中的Image模块

# L = 0.299R + 0.587G + 0.114B

img2 = Image.open(photo_file)

grey_img2 = img2.convert('L')

grey_img22 = np.array(grey_img2)

print(type(grey_img22))

  使用python中的图像处理库PIL来实现不同图像格式的转化,对于彩色图像,不管其图像格式是PNG,还是BMP,还是JPG,在PIL中,使用Image模块的open()函数打开后,返回的图像对象的模式都是“RGB”。而对于灰度图像,不管其图像格式是PNG,还是BMP,或者JPG,打开后,其模式为“L”。

1.4  图像灰度化练习

  下面代码是调用cvtColor()函数将图像进行灰度化处理的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#_*_coding:utf-8_*_

import cv2

import numpy as np

import matplotlib.pyplot as plt

  

#读取原始图片

src1 = cv2.imread('irving.jpg')

src2 = cv2.cvtColor(src1, cv2.COLOR_BGR2RGB)

  

#图像灰度化处理

grayImage = cv2.cvtColor(src1, cv2.COLOR_RGB2GRAY)

grayImage1 = cv2.imread('irving.jpg', 0)

# #显示图像

# cv2.imshow("src", src)

# cv2.imshow("result", grayImage)

  

# #等待显示

# cv2.waitKey(0)

# cv2.destroyAllWindows()

 

plt.subplot(2,2,1), plt.imshow(src1)

plt.xticks([]), plt.yticks([])

plt.title('origin image BGR')

plt.subplot(2,2,2), plt.imshow(src2)

plt.xticks([]), plt.yticks([])

plt.title('origin image RGB')

plt.subplot(2,2,3), plt.imshow(grayImage)

plt.xticks([]), plt.yticks([])

plt.title('BGR2gray image')

plt.subplot(2,2,4), plt.imshow(grayImage1)

plt.xticks([]), plt.yticks([])

plt.title('gray image')

plt.show()

  处理结果如下:

   注意:灰度化的图,在matplotlib里显示图像不是灰色的,这里因为通道转换问题,这里我们在OpenCV中显示则正常。

 

2,基于像素操作的图像灰度化处理

  基于像素操作的图像灰度化处理方法,主要是最大值灰度处理、平均灰度处理和加权平均灰度处理方法。其实之前也学习过,这里再整理一遍。

2.1  最大值灰度处理方法

  该方法的灰度值等于彩色图像R、G、B三个分量中的最大值,其公式如下:

  这种方法灰度化处理后的灰度图亮度很高(即灰度偏亮)

  代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#_*_coding:utf-8_*_

import cv2 

import numpy as np 

import matplotlib.pyplot as plt

 

#读取原始图像

img = cv2.imread('irving.jpg')

src = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

 

#获取图像高度和宽度

height = img.shape[0]

width = img.shape[1]

 

#创建一幅图像

grayimg = np.zeros((height, width, 3), np.uint8)

 

#图像最大值灰度处理

for in range(height):

    for in range(width):

        #获取图像R G B最大值

        gray = max(img[i,j][0], img[i,j][1], img[i,j][2])

        #灰度图像素赋值 gray=max(R,G,B)

        grayimg[i,j] = np.uint8(gray)

 

# #显示图像

# cv2.imshow("src", img)

# cv2.imshow("gray", grayimg)

 

# #等待显示

# cv2.waitKey(0)

# cv2.destroyAllWindows()

 

plt.subplot(1,3,1), plt.imshow(img)

plt.xticks([]), plt.yticks([])

plt.title('origin image BGR')

plt.subplot(1,3,2), plt.imshow(src)

plt.xticks([]), plt.yticks([])

plt.title('origin image RGB')

plt.subplot(1,3,3), plt.imshow(grayimg)

plt.xticks([]), plt.yticks([])

plt.title('max gray image')

plt.show()

  图如下:

2.2   平均灰度处理方法

  该方法的灰度值等于彩色图像 R,G,B 是哪个分量灰度值的求和平均值,其计算公式如下所示:

  这种方法产生的灰度图像比较柔和。

   平均灰度处理方法实现代码如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#_*_coding:utf-8_*_

import cv2 

import numpy as np 

import matplotlib.pyplot as plt

 

#读取原始图像

img = cv2.imread('irving.jpg')

 

src = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

 

#获取图像高度和宽度

height = img.shape[0]

width = img.shape[1]

 

#创建一幅图像

grayimg = np.zeros((height, width, 3), np.uint8)

 

#图像平均灰度处理方法

for in range(height):

    for in range(width):

        #灰度值为RGB三个分量的平均值

        gray = (int(img[i,j][0]) + int(img[i,j][1]) + int(img[i,j][2]))  /  3

        grayimg[i,j] = np.uint8(gray)

 

# #显示图像

# cv2.imshow("src", img)

# cv2.imshow("gray", grayimg)

 

# #等待显示

# cv2.waitKey(0)

# cv2.destroyAllWindows()

 

plt.subplot(1,3,1), plt.imshow(img)

plt.xticks([]), plt.yticks([])

plt.title('origin image BGR')

plt.subplot(1,3,2), plt.imshow(src)

plt.xticks([]), plt.yticks([])

plt.title('origin image RGB')

plt.subplot(1,3,3), plt.imshow(grayimg)

plt.xticks([]), plt.yticks([])

plt.title('mean gray image')

plt.show()

      效果如下:

2.3   加权平均灰度处理方法

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

  这种灰度化得到的灰度图像效果最好。

   加权平均灰度处理方法实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#_*_coding:utf-8_*_

import cv2 

import numpy as np 

import matplotlib.pyplot as plt

 

#读取原始图像

img = cv2.imread('irving.jpg')

 

src = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

 

#获取图像高度和宽度

height = img.shape[0]

width = img.shape[1]

 

#创建一幅图像

grayimg = np.zeros((height, width, 3), np.uint8)

 

#加权平均灰度处理方法

for in range(height):

    for in range(width):

        #灰度加权平均法

        gray = 0.30 * img[i,j][0] + 0.59 * img[i,j][1] + 0.11 * img[i,j][2]

        grayimg[i,j] = np.uint8(gray)

 

# #显示图像

# cv2.imshow("src", img)

# cv2.imshow("gray", grayimg)

 

# #等待显示

# cv2.waitKey(0)

# cv2.destroyAllWindows()

 

plt.subplot(1,3,1), plt.imshow(img)

plt.xticks([]), plt.yticks([])

plt.title('origin image BGR')

plt.subplot(1,3,2), plt.imshow(src)

plt.xticks([]), plt.yticks([])

plt.title('origin image RGB')

plt.subplot(1,3,3), plt.imshow(grayimg)

plt.xticks([]), plt.yticks([])

plt.title('weighted mean gray image')

plt.show()

   效果如下:

3,图像灰度线性变换原理

  图像的灰度线性变换是通过建立灰度映射来调整原始图像的灰度,从而改善图像的质量,凸显图像的细节,提高图像的对比度。灰度线性变换的计算公式如下所示:

  该公式中DB表示灰度线性变换后的灰度值,DA表示变换前输入图像的灰度值,α和b为线性变换方程f(D)的参数,分别表示斜率和截距。

  • 当α=1,b=0时,保持原始图像
  • 当α=1,b!=0时,图像所有的灰度值上移或下移
  • 当α=-1,b=255时,原始图像的灰度值反转
  • 当α>1时,输出图像的对比度增强
  • 当0<α<1时,输出图像的对比度减小
  • 当α<0时,原始图像暗区域变亮,亮区域变暗,图像求补

  如下图所示,显示了图像灰度线性变换对应的效果图:

    下面一一学习。

3.1 图像灰度上移变换

  该算法将实现图像灰度值的上移,从而提升图像的亮度,由于图像的灰度值位于0到255区间之内,所以需要对灰度值进行溢出判断。其实现代码如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 图像灰度转换

grayimage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

# 获取图像高度和宽度

height = grayimage.shape[0]

width = grayimage.shape[1]

 

# 创建一幅图像

result = np.zeros((height, width), np.uint8)

 

# 图像灰度上移变换  DB = DA + 50

for in range(height):

    for in range(width):

        if (int(grayimage[i, j] + 50) > 255):

            gray = 255

        else:

            gray = int(grayimage[i, j] + 50)

        result[i, j] = np.uint8(gray)

 

# 显示图像

cv2.imshow("Gray Image", grayimage)

cv2.imshow("Result", result)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

  其输出结果如下所示:

   我们可以看到,图像的所有灰度值上移 50,图像变得更白了。(注意:纯黑色对应的灰度值为0,纯白色的对应的灰度值为255)

3.2  图像对比度增强变换

  该算法将增强图像的对比度。Python实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 图像灰度转换

grayimage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

# 获取图像高度和宽度

height = grayimage.shape[0]

width = grayimage.shape[1]

 

# 创建一幅图像

result = np.zeros((height, width), np.uint8)

 

# 图像对比度增强变换  DB = DA * 1.5

for in range(height):

    for in range(width):

        if (int(grayimage[i, j] * 1.5) > 255):

            gray = 255

        else:

            gray = int(grayimage[i, j] * 1.5)

        result[i, j] = np.uint8(gray)

 

# 显示图像

cv2.imshow("Gray Image", grayimage)

cv2.imshow("Result", result)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

   结果如下:

   结果就是图像所有的灰度值增强 1.5倍,我们发现变亮了。

3.3  图像对比度减弱变换

  该算法将减弱图像的对比度,Python实现代码如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 图像灰度转换

grayimage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

# 获取图像高度和宽度

height = grayimage.shape[0]

width = grayimage.shape[1]

 

# 创建一幅图像

result = np.zeros((height, width), np.uint8)

 

# 图像对比度减弱变换  DB = DA * 0.8

for in range(height):

    for in range(width):

        if (int(grayimage[i, j] * 0.8) > 255):

            gray = 255

        else:

            gray = int(grayimage[i, j] * 0.8)

        result[i, j] = np.uint8(gray)

 

# 显示图像

cv2.imshow("Gray Image", grayimage)

cv2.imshow("Result", result)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

  结果如下所示:

   我们从结果可以看出,图像的所有灰度值减弱,图像变得更暗。

3.4  图像灰度反色变换

  反色变换又称线性灰度求补变换,它是对原图像的像素值进行反转,即黑色变为白色,白色变为黑色的过程。其Python实现代码如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 图像灰度转换

grayimage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

# 获取图像高度和宽度

height = grayimage.shape[0]

width = grayimage.shape[1]

 

# 创建一幅图像

result = np.zeros((height, width), np.uint8)

 

# 图像灰度反色变换  DB = 255 - DA

for in range(height):

    for in range(width):

        gray = 255 - grayimage[i, j]

        result[i, j] = np.uint8(gray)

 

# 显示图像

cv2.imshow("Gray Image", grayimage)

cv2.imshow("Result", result)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

   其结果如下所示:

   我们发现,图像处理前后的灰度值是互补的。

  注意:图像灰度反色变换在医学图像处理中有一定的应用,如下图所示:

4,图像灰度非线性变换

  图像的灰度非线性变换主要包括对数变换,幂次变换,指数变换,分段函数变换,通过非线性关系对图像进行灰度处理,下面学习三种常见类型的灰度非线性变换。

4.1 图像灰度非线性变换:DB = DA * DA / 255

  下面我们将原始图像的灰度值按照DB = DA * DA / 255 的公式进行非线性变换,其代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 图像灰度转换

grayimage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

# 获取图像高度和宽度

height = grayimage.shape[0]

width = grayimage.shape[1]

 

# 创建一幅图像

result = np.zeros((height, width), np.uint8)

 

# 图像灰度非线性变换  DB = DA * DA / 255

for in range(height):

    for in range(width):

        gray = int(grayimage[i, j]) * int(grayimage[i, j]) / 255

        result[i, j] = np.uint8(gray)

 

# 显示图像

cv2.imshow("Gray Image", grayimage)

cv2.imshow("Result", result)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

   结果如下:

4.2 图像灰度对数变换

  图像灰度的对数变换一般表示如公式所示:

  其中 c 为尺度比较常数,DA为原始图像灰度值,DB为变换后的目标灰度值。如下图所示,它表示对数曲线下的灰度值变换情况。

  

由于对数曲线在像素值较低的区域斜率大,在像素值高的区域斜率较小,所以图像经过对数变换后,较暗区域的对比度将有所提升。这种变换可用于增强图像的暗部细节,从而用来扩展被压缩的高值图像中的较暗像素。

  对数变换实现了扩展低灰度值而压缩高灰度值的效果,被广泛的应用于频谱图像的显示中。一个典型的应用是傅里叶频谱,其动态范围可能宽达 0 ~ 106 直接显示频谱时,图像显示设备的动态范围往往不能满足要求,从而丢失大量的暗部细节;而在使用对数变换之后,图像的动态范围被合理的非线性压缩,从而可以清晰地显示。在下图中,未经变换的频谱经过对数变换后,增加了低灰度区域的对比度,从而增强暗部的细节。(关于傅里叶变换,我后面会学习)

   下面代码实现了图像灰度的对数变换:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

 

# 绘制曲线

def log_plot(c):

    x = np.arange(0, 256, 0.01)

    y = c * np.log(1 + x)

    plt.plot(x, y, 'r', linewidth=1)

    # 正常显示中文标签

    plt.rcParams['font.sans-serif'] = ['SimHei']

    plt.title(u'对数变换函数')

    plt.xlim(0, 255), plt.ylim(0, 255)

    plt.show()

 

 

# 对数变换

def log(c, img):

    output = c * np.log(1.0 + img)

    output = np.uint8(output + 0.5)

    return output

 

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 绘制对数变换曲线

log_plot(42)

 

# 图像灰度对数变换

result = log(42, img)

 

# 显示图像

cv2.imshow("Image", img)

cv2.imshow("Result", result)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

   结果如下图:

  对应的对数函数曲线如图所示:

  对数变换对于整体对比度偏低并且灰度值偏低的图像增强效果较好。

4.3  图像灰度伽马变换

  gamma矫正通常用于电汇和监视器系统中重现摄像机拍摄的画面,在图像处理中也可用于调节图像的对比度,减少图像的光照不均和局部阴影。

  gamma变换又称为指数变换或幂次变换,是另外一种常用的灰度非线性变换。图像灰度的伽马变换一般表示如下:

  gamma矫正示意图:

   结合上图看gamma矫正的作用:

  • 1,当 gamma<1时,如虚线所示,在低灰度值区域内,动态范围变大,进而图像对比度增强(当 x € [0, 0.2] 时,y的范围从 [0, 0.218] 扩大到 [0, 0.5]);在高灰度值区域内,动态范围变小,图像对比度降低(当 x € [ 0.8, 1]时,y的范围从 [0.8, 1] 缩小到 [0.9, 1],同时,图像整体的灰度值变大)。简单来说:会拉伸图像中灰度级较低的区域,压缩灰度级较高的部分。
  • 2,当 gamma >1时,如实线所示,低灰度值区域的动态范围变小,高灰度值区域在动态范围内变大,降低了低灰度值区域图像对比度。提高了高灰度值区域图像对比度。同时,图像整体的灰度值变小。简单来说:会拉伸体现中灰度级较高的区域,压缩灰度级较低的部分。
  • 3,当 gamma=1时,该灰度变换是线性的,此时通过线性方式改变原图像。

   当一张图片的像素在颜色空间的值都比较大(曝光过度)或者比较小(曝光不足)的情况下,选用合理的R值能减少或者增加其颜色亮度,并使颜色分布更为均匀和丰富,图片效果得到明显的改善。但是这种方法并非对所有在曝光上有缺陷的图片都适用,这是在使用这个方法的时候必须要注意的。

  当一张曝光过度的图片中存在颜色较暗的区域(比如背光面,阴影,颜色较深的物体),由 gamma函数图像可以看出,当选取较小的R值,过度曝光得不到充分的改善;而当选取较大的R值,该区域将会变成黑乎乎的一片;同样,当一张曝光不足的图片存在颜色较亮的区域(比如天空,白色背景,反光物等),如果选取R值较大,则曝光不足得不到改善;而选取较小的R值,这个区域变得更亮,从图片上看就觉得很“扎眼”。

  因此,虽然这种方法对图片的曝光率具有较好的调整效果,但是如果素材敏感差异较大,在调整较暗或较亮区域时,要注意减少对较暗或较亮区域的影响。事实上可以根据相同的原理,利用插值的方法构造相对应的处理函数,以得到更加精致的处理效果。

  使用Python实现,可以通过除以像素最大值,先将图像像素值调整到 0~1之间,然后进行不同的 gamma值的gamma矫正,python代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

import cv2

import numpy as np

import matplotlib.pyplot as plt

 

 

# 绘制曲线

def gamma_plot(c, gamma):

    x = np.arange(0, 256, 0.01)

    # y = c * x ** gamma

    y = c * np.power(x, gamma)

    plt.plot(x, y, 'r', linewidth=1)

    plt.rcParams['font.sans-serif'] = ['SimHei']  # 正常显示中文标签

    plt.title(u'伽马变换函数')

    plt.xlim([0, 255]), plt.ylim([0, 255])

    plt.show()

 

 

# 伽玛变换

def gamma(img, c, gamma):

    # 映射表必须为0~255(改成其他会报错)

    gamma_table = c * [np.power(x/255.0, gamma) * 255.0 for in range(256)]

    # Numpy数组默认数据类型为 int32,需要将数据类型转换为opencv图像适合使用的无符号八位整形

    # round() 方法返回浮点数x的四舍五入值。

    gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)

    output_img = cv2.LUT(img, gamma_table)

    return output_img

 

def gamma_1(img, c, gamma):

    # 映射表必须为0~255(改成其他会报错)

    output_img = c * np.power(img / float(np.max(img)), gamma) * 255.0

    output_img = np.uint8(output_img)

    return output_img

 

 

# 读取原始图像

img = cv2.imread('irving.jpg')

 

# 将图像转换为灰度,我们需要使用灰度图做gamma矫正

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

# 绘制伽玛变换曲线

gamma_plot(1, 4.0)

 

# 图像灰度伽玛变换

result = gamma(gray, 1, 0.4)

result1 = gamma_1(gray, 1, 0.4)

 

# 显示图像

cv2.imshow("Image", img)

cv2.imshow("Result", result)

cv2.imshow("Result 1", result1)

 

# 等待显示

cv2.waitKey(0)

cv2.destroyAllWindows()

  除以最大值的目的是归一化,将像素值调整到0~1之间。

  我们看结果:

 

4.3  opencv中  cv2.LUT() 函数

  此函数主要用来其到突出的有用信息,增强图像的光对比度的作用。通过对input的灰度像素的改变,可以通过映射的关系得到需要输出的灰度像素矩阵 output。

  或者这样讲:使用查找表中的值填充输出数组。我们看源码解析:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

def LUT(src, lut, dst=None): # real signature unknown; restored from __doc__

    """

    LUT(src, lut[, dst]) -> dst

    .   @brief Performs a look-up table transform of an array.

    对数组执行查找表转换。

    .  

    .   The function LUT fills the output array with values from the look-up table. Indices of the entries

    .   are taken from the input array. That is, the function processes each element of src as follows:

    函数LUT使用查找表中的值填充输出数组。 条目的索引取自输入数组。

    也就是说,该函数按以下方式处理src的每个元素:

    .   \f[\texttt{dst} (I)  \leftarrow \texttt{lut(src(I) + d)}\f]

    .   where

    .   \f[d =  \fork{0}{if \(\texttt{src}\) has depth \(\texttt{CV_8U}\)}{128}{if \(\texttt{src}\) has depth \(\texttt{CV_8S}\)}\f]

    .   @param src input array of 8-bit elements. 8位元素的输入数组。

     

    .   @param lut look-up table of 256 elements; in case of multi-channel input array, the table should

    .   either have a single channel (in this case the same table is used for all channels) or the same

    .   number of channels as in the input array.

    256个元素的查询表;

    如果是多通道输入数组,则该表应具有单个通道

    (在这种情况下,所有通道都使用相同的表)或与输入阵列中的通道数相同。

     

    .   @param dst output array of the same size and number of channels as src, and the same depth as lut.

    输出数组,其大小和通道数与src相同,深度与lut相同。

    .   @sa  convertScaleAbs, Mat::convertTo

    """

    pass

首先读取图片,然后灰度化,最后转化为数组

1

2

3

4

5

6

7

8

9

import numpy as np

form PIL import Image

 

# 使用PIL库中的Image模块

# L = 0.299R + 0.587G + 0.114B

img2 = Image.open(photo_file)

grey_img2 = img2.convert('L')

grey_img22 = np.array(grey_img2)

print(type(grey_img22))

  使用python中的图像处理库PIL来实现不同图像格式的转化,对于彩色图像,不管其图像格式是PNG,还是BMP,还是JPG,在PIL中,使用Image模块的open()函数打开后,返回的图像对象的模式都是“RGB”。而对于灰度图像,不管其图像格式是PNG,还是BMP,或者JPG,打开后,其模式为“L”。

参考文献:

https://blog.csdn.net/Rothwale/article/details/79189032

https://blog.csdn.net/Eastmount/article/details/88785768

 https://blog.csdn.net/akadiao/article/details/79679306

https://blog.csdn.net/Eastmount/article/details/88858696

 https://blog.csdn.net/Eastmount/article/details/88929290

  


更多精彩内容请访问FlyAI-AI竞赛服务平台;为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台;每周免费提供项目开源算法样例,支持算法能力变现以及快速的迭代算法模型。

挑战者,都在FlyAI!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换) 的相关文章

  • Python Popen 与 psexec 挂起 - 不良结果

    我对 subprocess Popen 和我认为是管道的问题有疑问 我有以下代码块 从 cli 运行时 100 都不会出现问题 p subprocess Popen psexec serverName get cmd c ver echo
  • django_openid_auth TypeError openid.yadis.manager.YadisServiceManager 对象不是 JSON 可序列化

    I used django openid auth在我的项目上 一段时间以来它运行得很好 但今天 我测试了该应用程序并遇到了这个异常 Environment Request Method GET Request URL http local
  • 我怎样才能更多地了解Python的内部原理? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我使用Python编程已经有半年多了 我对Python内部更感兴趣 而不是使用Python开发应用程序
  • python 中的代表

    我实现了这个简短的示例来尝试演示一个简单的委托模式 我的问题是 这看起来我已经理解了委托吗 class Handler def init self parent None self parent parent def Handle self
  • 如何正确地将 MIDI 刻度转换为毫秒?

    我正在尝试将 MIDI 刻度 增量时间转换为毫秒 并且已经找到了一些有用的资源 MIDI Delta 时间刻度到秒 http www lastrayofhope co uk 2009 12 23 midi delta time ticks
  • Python逻辑运算符优先级[重复]

    这个问题在这里已经有答案了 哪个运算符优先4 gt 5 or 3 lt 4 and 9 gt 8 这会被评估为真还是假 我知道该声明3 gt 4 or 2 lt 3 and 9 gt 10 显然应该评估为 false 但我不太确定 pyth
  • 如何使用 Plotly 中的直方图将所有离群值分入一个分箱?

    所以问题是 我可以在 Plotly 中绘制直方图 其中所有大于某个阈值的值都将被分组到一个箱中吗 所需的输出 但使用标准情节Histogram类我只能得到这个输出 import pandas as pd from plotly import
  • 从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

    我已经查看了很多问题 但仍然无法完全弄清楚 我正在使用 PyQt 并且希望能够运行ffmpeg i file mp4 file avi并获取流式输出 以便我可以创建进度条 我看过这些问题 ffmpeg可以显示进度条吗 https stack
  • Pandas 中允许重复列

    我将一个大的 CSV 包含股票财务数据 文件分割成更小的块 CSV 文件的格式不同 像 Excel 数据透视表之类的东西 第一列的前几行包含一些标题 公司名称 ID 等在以下列中重复 因为一家公司有多个属性 而不是一家公司只有一栏 在前几行
  • 从零开始的 numpy 形状意味着什么

    好的 我发现数组的形状中可以包含 0 对于将 0 作为唯一维度的情况 这对我来说是有意义的 它是一个空数组 np zeros 0 但如果你有这样的情况 np zeros 0 100 让我很困惑 为什么这么定义呢 据我所知 这只是表达空数组的
  • 在Python中调整图像大小

    我有一张尺寸为 288 352 的图像 我想将其大小调整为 160 240 我尝试了以下代码 im imread abc png img im resize 160 240 Image ANTIALIAS 但它给出了一个错误TypeErro
  • python suds SOAP 请求中的名称空间前缀错误

    我使用 python suds 来实现客户端 并且在发送的 SOAP 标头中得到了错误的命名空间前缀 用于定义由element ref 在 wsdl 中 wsdl 正在引用数据类型 xsd 文件 请参见下文 问题出在函数上GetRecord
  • TensorFlow的./configure在哪里以及如何启用GPU支持?

    在我的 Ubuntu 上安装 TensorFlow 时 我想将 GPU 与 CUDA 结合使用 但我却停在了这一步官方教程 http www tensorflow org get started os setup md 这到底是哪里 con
  • 奇怪的 MySQL Python mod_wsgi 无法连接到 'localhost' (49) 上的 MySQL 服务器问题

    StackOverflow上也有类似的问题 但我还没有发现完全相同的情况 这是在使用 MySQL 的 OS X Leopard 机器上 一些起始信息 MySQL Server version 5 1 30 Apache 2 2 13 Uni
  • 首先对列表中最长的项目进行排序

    我正在使用 lambda 来修改排序的行为 sorted list key lambda item item lower len item 对包含元素的列表进行排序A1 A2 A3 A B1 B2 B3 B 结果是A A1 A2 A3 B
  • 如何在 OSX 上安装 numpy 和 scipy?

    我是 Mac 新手 请耐心等待 我现在使用的是雪豹 10 6 4 我想安装numpy和scipy 所以我从他们的官方网站下载了python2 6 numpy和scipy dmg文件 但是 我在导入 numpy 时遇到问题 Library F
  • 默认情况下,Keras 自定义层参数是不可训练的吗?

    我在 Keras 中构建了一个简单的自定义层 并惊讶地发现参数默认情况下未设置为可训练 我可以通过显式设置可训练属性来使其工作 我无法通过查看文档或代码来解释为什么会这样 这是应该的样子还是我做错了什么导致默认情况下参数不可训练 代码 im
  • Tkinter - 浮动窗口 - 调整大小

    灵感来自this https stackoverflow com a 22424245 13629335问题 我想为我的根窗口编写自己的调整大小函数 但我刚刚注意到我的代码显示了一些性能问题 如果你快速调整它的大小 你会发现窗口没有像我希望
  • 在Python中按属性获取对象列表中的索引

    我有具有属性 id 的对象列表 我想找到具有特定 id 的对象的索引 我写了这样的东西 index 1 for i in range len my list if my list i id specific id index i break
  • 从 Twitter API 2.0 获取 user.fields 时出现问题

    我想从 Twitter API 2 0 端点加载推文 并尝试获取标准字段 作者 文本 和一些扩展字段 尤其是 用户 字段 端点和参数的定义工作没有错误 在生成的 json 中 我只找到标准字段 但没有找到所需的 user fields 用户

随机推荐

  • win10系统 总是显示执行此操作需要Internet

    最近在重新设置电脑登录方式时 系统总是显示 执行此操作需要Internet 解决方法如下 首先右键开始图标 以管理员身份打开PowerShell 然后输入 netsh winsock reset 进行重置 winsock是Windows网络
  • 关于对数据结构的理解

    数据结构是计算机存储 组织数据的方式 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合 数据结构反映数据的内部构成 即数据由那部分构成 以什么方式构成 以及数据元素之间呈现的结构 数据结构就是研究数据的逻辑结构和物理结构以及它们之
  • 数据库总结(七)

    数据库设计 7 1 数据库设计概述 1 数据库设计 数据库设计是指对于一个给定的应用环境 构造 设计 优化的数据库逻辑模式和物理结构 并据此建立数据库及其应用系统 使之能够有效地存储和管理数据 满足各种用户的应用需求 包括信息管理要求和数据
  • Spring AOP 剖析(6)

    Spring AOP 的底层实现机制 2 Spring AOP 中的 Pointcut 6 扩展 Pointcut 如何前面的 Pointcut 类型都无法满足要求 这种情况下可以扩展 Spring AOP 的 Pointcut 给出自定义
  • web复习之从头到尾看看(1)

    主要是一些我认为自己没有掌握的细节性问题 仅供参考 欢迎大家一起学习 留言 你认为最有可能考的内容 换行标签 lt gt 内加br br span 不能包含 div 与 p 超链接 a href 链接内容 target 在何处打开 self
  • Python绘制三角函数图像

    可以使用Python的matplotlib库来绘制三角函数图像 首先 定义一个x值的范围 然后使用matplotlib的plot 函数绘制三角函数 最后使用matplotlib的show 函数显示图像
  • HTML 取消input自动提示

    input 输入框有提示功能 当你之前输入过一些内容 你下次打入相关字符的时候 默认会有之前输入的一些相关的字符的提示 这个提示一般来说还是很好的 但是 有时候 我们想自己输入 不想要提示 如果不需要提示 则将 autocomplete设置
  • ubuntu的终端命令提示符太长的修改方法总结

    2019独角兽企业重金招聘Python工程师标准 gt gt gt ubuntu的终端命令提示符太长 主要原因 1 计算机名太长 2 多层直接显示出来 针对计算机名太长的处理 如 下面的计算机名提示太长了 ningcaichen virtu
  • Java的byte类型详解

    前言 byte这个单词是Java八种基本数据类型之一字节的关键字 在计算机存储中以字节为单位 8位比特 bit 组成一个字节 为什么弄清楚byte这么重要呢 因为智能硬件的数据传输大部分协议都是按字节一位一位来解析的 对于字节的运算十分频繁
  • 备战蓝桥杯-二分查找(附多道题解和详细分析)

    二分典型例题 备战蓝桥杯系列全部文章 分享看过的高赞的文章 有助于你对于二分的理解 巨人的肩膀 知乎 二分的解释 LeetCode二分的解释 给定一个按照升序排列的长度为 nn 的整数数组 以及 qq 个查询 对于每个查询 返回一个元素 k
  • 直播邀约|8个数字了解2023腾讯全球数字生态大会

    2023腾讯数字生态大会 一起来看看吧
  • ❤ npm install 时报Error: spawn git ENOENT

    npm install 时报Error spawn git ENOENT 原因 主要是因为由于 git 的环境变量未设置导致 所以安装一下git 的环境变量就O了 步骤如下 设置 gt gt 系统 gt gt 高级系统设置 gt gt 高级
  • linux系统下修改文件夹目录权限

    文件夹权限问题 Linux Fedora Ubuntu修改文件 文件夹权限的方法差不多 很多人开始接触Linux时都很头痛Linux的文件权限问题 这里告诉大家如何修改Linux文件 文件夹权限 以主文件夹下的一个名为cc的文件夹为例 下面
  • nodejs第五天 npm yarn pnpm 包管理器

    文章目录 npm package json 安装包 全局安装 配置镜像 yarn 安装使用 镜像配置 pnpm 使用 镜像 npm node中的包管理器叫做npm node package manage 我们可以将自己开发的包上传到npm中
  • 数据结构--循环队列的c语言实现(超详细注释/实验报告)

    数据结构 循环队列的c语言实现 超详细注释 实验报告 知识小回顾 队列 Queue 是另一种限定性的线性表 它只允许再表的一端插入元素 而再另一端删除元素 多以队列具有先进先出 First In First Out FIFO 的特性 这与我
  • dmmbus地址_busdmm.us服务器iP

    2019 10 09 2020 12 19 173 252 100 21 2019 10 09 2020 12 19 31 13 74 1 2020 09 05 2020 12 19 104 244 43 208 2020 09 05 20
  • Mac系统创建python3.7虚拟环境

    mac系统python3 7安装虚拟环境 什么叫虚拟环境呢 python特有的一种软件环境 创建多个python环境 各个环境之间完全隔离 互不影响 它可以用来解决Python项目开发和运行过程中的依赖项和版本问题 而不必和其他项目的Pyt
  • dfs找不到网络路径 windows_DFS 复制服务已启动位于本地路径 C:\WINDOWS\SYSVOL\domain 上的 SYSVOL,并正在...

    公司新建域控由于分公司需要辅助域控 就新建了一台额外域控 但是该域控建好后发现组策略不生效 检查sysvol文件夹一片空白 肯定是没有从主域控复制过来 使用dcdiag检查 有下面报错 目录服务器诊断 正在执行初始化设置 正在尝试查找主服务
  • Android -- Activity and Intent

    Android Activity and Intent Activity Activity Lifecycle Intent 显式Intent 隐式Intent Intent属性 Intent Examples Activity activ
  • OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)

    人工智能学习离不开实践的验证 推荐大家可以多在FlyAI AI竞赛服务平台多参加训练和竞赛 以此来提升自己的能力 FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台 每周免费提供项目开源算法样例 支持算法能力变现以及快