• 【OpenCV-Python-课程学习(贾)】OpenCV3.3课程学习笔记:图像色彩空间的转换(cvtColor、)


    一、imread()的grayscale和cvtColor()的区别

    在图像加载API中,我们可以看到imread()有一个参数flags ,这个参数有一个选项是cv.IMREAD_GRAYSCALE,意思是将原图像转换为灰度图后返回。

    官方文档解释是:

    If set, always convert image to the single channel grayscale image (codec internal conversion).

    如果设置,总是将图像转换成单通道的灰度图(采取内部转换编码)。

     并且在imread()的API文档中也有一个注释

    When using IMREAD_GRAYSCALE, the codec's internal grayscale conversion will be used, if available. Results may differ to the output of cvtColor().

    当用参数IMREAD_GRAYSCALE时,如果内部灰度转换编码可获得,那么它将被使用。结果与cvtColor()的有差异。cvtColor()

    可以看出来,在读取图像时直接转换成灰度图和先读取全色再用cvtColor()转成灰度,结果是不一样的。

    这个区别虽然存在,但是非常小,仅有部分区域、一些像素点不同;具体可以参考Stack Overflow的文章,测试代码如下

    1. import cv2
    2. import numpy as np
    3. path = 'some/path/to/color/image.jpg'
    4. # Load color image (BGR) and convert to gray
    5. img = cv2.imread(path)
    6. img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    7. # Load in grayscale mode
    8. img_gray_mode = cv2.imread(path, 0)
    9. # diff = img_gray_mode - img_gray
    10. diff = cv2.bitwise_xor(img_gray,img_gray_mode)
    11. print(np.sum(diff ))
    12. # 输出结果不为0,对于一个494 x 750=370500的图像,结果为6143,不是很大
    13. cv2.imshow('diff', diff)
    14. # 最后会发现图像不全是黑色,说明img_gray和img_gray_mode有像素点不一样
    15. cv2.waitKey()

    二、对cvtColor()的讲解

    cvtColor()不仅可以将三通道转成灰度单通道,也可将BGR的三通道转成其他类型的三通道,比如HSV。

    以下摘录于官网cvtColor()文档

    1. cv::COLOR_BGR2BGRA = 0,
    2. cv::COLOR_RGB2RGBA = COLOR_BGR2BGRA,
    3. cv::COLOR_BGRA2BGR = 1,
    4. cv::COLOR_RGBA2RGB = COLOR_BGRA2BGR,
    5. cv::COLOR_BGR2RGBA = 2,
    6. cv::COLOR_RGB2BGRA = COLOR_BGR2RGBA,
    7. cv::COLOR_RGBA2BGR = 3,
    8. cv::COLOR_BGRA2RGB = COLOR_RGBA2BGR,
    9. cv::COLOR_BGR2RGB = 4,
    10. cv::COLOR_RGB2BGR = COLOR_BGR2RGB,
    11. cv::COLOR_BGRA2RGBA = 5,
    12. cv::COLOR_RGBA2BGRA = COLOR_BGRA2RGBA,
    13. cv::COLOR_BGR2GRAY = 6,
    14. cv::COLOR_RGB2GRAY = 7,
    15. cv::COLOR_GRAY2BGR = 8,
    16. cv::COLOR_GRAY2RGB = COLOR_GRAY2BGR,
    17. cv::COLOR_GRAY2BGRA = 9,
    18. cv::COLOR_GRAY2RGBA = COLOR_GRAY2BGRA,
    19. cv::COLOR_BGRA2GRAY = 10,
    20. cv::COLOR_RGBA2GRAY = 11,
    21. cv::COLOR_BGR2BGR565 = 12,
    22. cv::COLOR_RGB2BGR565 = 13,
    23. cv::COLOR_BGR5652BGR = 14,
    24. cv::COLOR_BGR5652RGB = 15,
    25. cv::COLOR_BGRA2BGR565 = 16,
    26. cv::COLOR_RGBA2BGR565 = 17,
    27. cv::COLOR_BGR5652BGRA = 18,
    28. cv::COLOR_BGR5652RGBA = 19,
    29. cv::COLOR_GRAY2BGR565 = 20,
    30. cv::COLOR_BGR5652GRAY = 21,
    31. cv::COLOR_BGR2BGR555 = 22,
    32. cv::COLOR_RGB2BGR555 = 23,
    33. cv::COLOR_BGR5552BGR = 24,
    34. cv::COLOR_BGR5552RGB = 25,
    35. cv::COLOR_BGRA2BGR555 = 26,
    36. cv::COLOR_RGBA2BGR555 = 27,
    37. cv::COLOR_BGR5552BGRA = 28,
    38. cv::COLOR_BGR5552RGBA = 29,
    39. cv::COLOR_GRAY2BGR555 = 30,
    40. cv::COLOR_BGR5552GRAY = 31,
    41. cv::COLOR_BGR2XYZ = 32,
    42. cv::COLOR_RGB2XYZ = 33,
    43. cv::COLOR_XYZ2BGR = 34,
    44. cv::COLOR_XYZ2RGB = 35,
    45. cv::COLOR_BGR2YCrCb = 36,
    46. cv::COLOR_RGB2YCrCb = 37,
    47. cv::COLOR_YCrCb2BGR = 38,
    48. cv::COLOR_YCrCb2RGB = 39,
    49. cv::COLOR_BGR2HSV = 40,
    50. cv::COLOR_RGB2HSV = 41,
    51. cv::COLOR_BGR2Lab = 44,
    52. cv::COLOR_RGB2Lab = 45,
    53. cv::COLOR_BGR2Luv = 50,

    最常见的是COLOR_BGR2GRAY=6、COLOR_GRAY2BGR=8、COLOR_BGR2HLS=52、COLOR_RGB2HLS=53、COLOR_BGR2HSV=40、COLOR_RGB2HSV=41

    语法很简单,就是cv2.cvtColor(src, code[, dst[, dstCn]])。

    参数src用来指定图片路径。

    参数code就是用来指定颜色空间转换规则。

    三、通道的分离与转换(split、merge)

    本章节讨论cv中的split,而不是numpy中的。

    cv中的split是分离图像通道,而numpy中的split是分割数组。

    假设img是一个BGR颜色图,使用split()分离通道后,由b, g, r接收。

    1. import cv2 as cv
    2. img = cv.imread('Snipaste_5.png')
    3. print(img.shape)
    4. b, g, r = cv.split(img)
    5. print(b.shape)
    6. print(g.shape)
    7. print(r.shape)
    8. cv.imshow("b", b)
    9. cv.imshow("g", g)
    10. cv.imshow("r", r)
    11. cv.waitKey(0)
    12. cv.destroyAllWindows()

    输出如下

    1. (769, 188, 3)
    2. (769, 188)
    3. (769, 188)
    4. (769, 188)
    5. (769, 188)

     原图如下

    输出的三个通道图片,是灰度图;这是因为b、g、r这三个图片变量的维度只有2维,而imshow()只所以能够顺利执行,就是因为会给三个图片变量额外扩充一维,第三维的大小为1,这时候各个通道的对应蓝、绿、红的数值自然就被视作灰度值了(或者看成第三维大小为3,拷贝性填充3个同样的值,同样也是灰度图)。

    比如假如通道b的某点取值为255,那么单独imshow()这个通道,这一点和(255, 255, 255)的显示相同,得以验证上面的结论。

    分离之后,我们可以对各个通道进行单独操作(加减乘除等),单独操作完成了就可以合并成一个完整的三色图。

    比如下面的代码,进一步对各个通道同时加上100(饱和运算),可以提高整体的亮度水平(虽然可能用不到),然后再用merge()融合在一起。

    1. import cv2 as cv
    2. img = cv.imread('Snipaste_5.png')
    3. print(img)
    4. print(img.shape)
    5. b, g, r = cv.split(img)
    6. b = cv.add(b, 100)
    7. g = cv.add(g, 100)
    8. r = cv.add(r, 100)
    9. cv.merge([b, g, r], img)
    10. print(b.shape)
    11. print(g.shape)
    12. print(r.shape)
    13. cv.imshow("b", b)
    14. cv.imshow("g", g)
    15. cv.imshow("r", r)
    16. cv.imshow("img", img)
    17. cv.waitKey(0)
    18. cv.destroyAllWindows()

    四、numpy式通道分离和合并

    如果您学过Numpy的数组切片、索引方面的知识,应该能够很简单地看出下面这两条语句等价,都是用来进行通道的分离。

    b, g, r = img[:, :, 0], img[:, :, 1], img[:, :, 2]

    b, g, r = cv2.split(img)

    同理,下面两条都是用来进行通道的合并。

    img[:, :, 0], img[:, :, 1], img[:, :, 2] = b, g, r

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

    因此,我们执行下面的代码

    1. import cv2 as cv
    2. img = cv.imread('Snipaste_5.png')
    3. copy = img.copy()
    4. b, g, r = cv.split(img)
    5. b1, g1, r1 = copy[:, :, 0], copy[:, :, 1], copy[:, :, 2]
    6. print((b == b1).all())
    7. print((g == g1).all())
    8. print((r == r1).all())
    9. b = cv.add(b, 100)
    10. g = cv.add(g, 100)
    11. r = cv.add(r, 100)
    12. b1 = cv.add(b1, 100)
    13. g1 = cv.add(g1, 100)
    14. r1 = cv.add(r1, 100)
    15. cv.merge([b, g, r], img)
    16. copy[:, :, 0], copy[:, :, 1], copy[:, :, 2] = b1, g1, r1
    17. cv.imshow("img", img)
    18. cv.imshow("copy", copy)
    19. cv.waitKey(0)
    20. cv.destroyAllWindows()

     

    最后输出的两张图片,完全一模一样!

  • 相关阅读:
    异地寄件教程分析
    ctf中ping命令执行绕过
    大数据学长面试之boss直聘面试题
    Android虚拟机与ClassLoader类加载机制
    商业化广告--体系学习-- 7 -- 行业蓝图篇 --广告产品发展路径
    论文阅读_自然语言模型加知识图谱_DKPLM
    超声波清洗机频率如何选择?高频和低频有什么区别
    如何给图片降噪?看完你就学会了
    国际结算业务
    数据分析-Pandas数据的直方图探查
  • 原文地址:https://blog.csdn.net/PSpiritV/article/details/126032178