【困惑实验记录】1)P模式转为灰度图再转为P模式,会发生什么变化?2)cv2读取灰度图获取的像素值与PIL获取的像素值是否相同?

结论

1)P模式转为灰度图再转为P模式,会发生什么变化?

答:结论如图,但是能发现像素点个数没有发生变化

像素值变化

  • L与第2次的P的像素值是完全相同的
  • 但是原始的P与第2的P已经不相同了(因此再通过P调色板模式转出的图像颜色也不相同了,原始的P是对应index=6的颜色(128, 0, 0),第2次的P是对应的index=38的颜色(0, 128, 192),见图2)。
【困惑实验记录】1)P模式转为灰度图再转为P模式,会发生什么变化?2)cv2读取灰度图获取的像素值与PIL获取的像素值是否相同?_第1张图片
【困惑实验记录】1)P模式转为灰度图再转为P模式,会发生什么变化?2)cv2读取灰度图获取的像素值与PIL获取的像素值是否相同?_第2张图片

2)cv2读取灰度图获取的像素值与PIL获取的像素值是否相同?

答:相同

(ps:cv2常见的两种读取灰度图方式,读取效果相同,实验代码可见博客:【困惑实验记录】cv2采用单通道读入或者转为灰度值的方式是否相同?答:相同)

实验代码

问题1

from collections import Counter
import numpy as np
import imgviz
from PIL import Image
import cv2


def getpixel_count(path):
    if isinstance(path, str):  # 如果传入的是字符串即地址,则需要再读取一下,否则就是已经读好了的PIL对象
        image = Image.open(path)
    else:
        image = path

    print(image.mode)  # P
    arr = []
    for w in range(image.size[0]):
        for h in range(image.size[1]):
            p = image.getpixel((w, h))
            if p not in arr:
                arr.append(p)
    print(arr)

    # 统计调色板情况
    palette = image.getpalette()  # 获取调色板
    count = Counter(np.array(image).flatten())
    print(count)
    return arr, count


def getpixel_cv(path):
    arr = []
    if isinstance(path, str):  # 如果传入的是字符串即地址,则需要再读取一下,否则就是已经读好了的PIL对象
        image = cv2.imread(path)
    else:
        image = path

    dim = image.ndim
    height, width = image.shape[:2]
    for h in range(height):
        for w in range(width):
            if dim == 3:  # 如果是3维图像,即RGB,则倒一下才是正确的RGB顺序
                p = image[h, w]
                p = (p[..., ::-1]).tolist()
            else:
                p = image[h, w]

            if p not in arr:  # 如果p不存在与arr中,则插入到列表中
                arr.append(p)
    print(arr)
    return arr


if __name__ == '__main__':
    test_path = 'self_P.png'  # P模式
    image = Image.open(test_path)
    arr, count = getpixel_count(image)

    # 转为灰度图
    image_L = image.convert("L")
    arr_L, count_L = getpixel_count(image_L)

    # 再转为P,测试与image的getpixel_count相同不
    image_L_P = image_L.convert("P")
    arr_L_P, count_L_P = getpixel_count(image_L_P)

    colormap = imgviz.label_colormap()  # 获取颜色映射
    image_L_P.putpalette(colormap.flatten())
    image_L_P.save('self_P2.png')

    print(arr_L == arr_L_P)  # True

问题2

from collections import Counter
import numpy as np
from PIL import Image
import cv2


def getpixel_count(path):
    if isinstance(path, str):  # 如果传入的是字符串即地址,则需要再读取一下,否则就是已经读好了的PIL对象
        image = Image.open(path)
    else:
        image = path

    print(image.mode)  # P
    arr = []
    for w in range(image.size[0]):
        for h in range(image.size[1]):
            p = image.getpixel((w, h))
            if p not in arr:
                arr.append(p)
    print(arr)

    # 统计调色板情况
    palette = image.getpalette()  # 获取调色板
    count = Counter(np.array(image).flatten())
    print(count)
    return arr, count


def getpixel_cv(path):
    arr = []
    if isinstance(path, str):  # 如果传入的是字符串即地址,则需要再读取一下,否则就是已经读好了的PIL对象
        image = cv2.imread(path)
    else:
        image = path

    dim = image.ndim
    height, width = image.shape[:2]
    for h in range(height):
        for w in range(width):
            if dim == 3:  # 如果是3维图像,即RGB,则倒一下才是正确的RGB顺序
                p = image[h, w]
                p = (p[..., ::-1]).tolist()
            else:
                p = image[h, w]

            if p not in arr:  # 如果p不存在与arr中,则插入到列表中
                arr.append(p)
    print(arr)
    return arr


if __name__ == '__main__':
    # 自己来用PIL做一张灰度图
    # -----------用cv2 灰度图读入,方式1---------- #
    self_gray_2 = Image.new(mode='L', size=(300, 300), color=100)  # 做一个灰度图
    self_gray_2.save('self_gray_2.png')
    print(f'mode = {self_gray_2.mode}')

    print('-----------way1 cv2读取-------------')
    image_1 = cv2.imread('self_gray_2.png', 0)  # 灰度图方式读入
    arr = getpixel_cv(image_1)

    print('\n-----------way2 PIL读取-------------')
    arr2, _ = getpixel_count('self_gray_2.png')

    print(arr == arr2)

结果:

mode = L
-----------way1 cv2读取-------------
[100]

-----------way2 PIL读取-------------
L
[100]
Counter({100: 90000})
True

你可能感兴趣的:(困惑实验记录,python,opencv,计算机视觉)