【OpenCV实现图像:用Python生成图像特效,报错ValueError: too many values to unpack (expected 3)】

文章目录

概要

Python是一种功能强大的编程语言,也是图像处理领域中常用的工具之一。通过使用Python的图像处理库(例如Pillow、OpenCV等),开发者可以实现各种各样的图像特效。这些特效包括但不限于:滤镜效果(如黑白、模糊、锐化等)、颜色转换、边缘检测、形状识别、图像合成和增强现实效果等。

在Python中,可以使用各种算法和技术来处理图像,例如卷积操作、颜色空间转换、形态学操作等。通过这些技术,开发者可以创建出令人惊叹的图像特效,用于美化照片、设计艺术作品、实现计算机视觉应用等。

图像处理的过程通常包括图像的读取、处理和保存。Python提供了简单而灵活的API,使得这些操作变得容易。开发者可以加载图像,对其进行各种操作,然后保存处理后的图像,以便后续使用或展示。

读入图像

bash 复制代码
# 导入Pillow库中的Image模块
from PIL import Image

# 打开名为"landscape.jpg"的图像文件
img = Image.open('./landscape.jpg')

# 获取图像的宽度和高度
width, height = img.size
print("图像宽度:", width, "图像高度:", height)

# 遍历图像的每个像素点
for x in range(0, height):
    for y in range(0, width):
        # 获取当前像素点的红色(r)、绿色(g)、蓝色(b)通道的像素值
        (r, g, b) = img.getpixel((x, y))
        
        # 打印每个像素点的RGB值
        print("像素点 (x:", x, ", y:", y, ") 的RGB值: (R:", r, ", G:", g, ", B:", b, ")")

在以上代码片段中,我们使用了Python的Pillow库来进行图像处理。首先,我们打开了名为"landscape.jpg"的样例图像,并获取了图像的宽度和高度。接着,我们使用嵌套的循环遍历图像的所有像素点。在每个像素点,我们使用getpixel((x, y))方法获取了红色(r)、绿色(g)、蓝色(b)三个通道的像素值。

通过这个嵌套循环,我们可以逐个打印出图像中每个像素的RGB值,从而了解图像的构成。这种方式可以作为图像处理的基础,为后续的图像处理操作提供了基础数据。这样的操作使得我们能够更深入地了解图像,为后续的图像处理任务提供了必要的信息。

报错;

bash 复制代码
D:\anaconda\envs\yolov5\python.exe E:\yolo项目\Opencv-project-main\Opencv-project-main\CVZone\guangliu\33.py 
图像宽度: 938 图像高度: 613
Traceback (most recent call last):
  File "E:\yolo项目\Opencv-project-main\Opencv-project-main\CVZone\guangliu\33.py", line 15, in <module>
    (r, g, b) = img.getpixel((x, y))
ValueError: too many values to unpack (expected 3)

Process finished with exit code 1

解决办法一:

错误提示表明在(r, g, b) = img.getpixel((x, y))这一行代码中,getpixel((x, y))返回的值不是期望的3个像素通道值(红、绿、蓝),而是更多的值,因此Python无法将这些值正确地分配给(r, g, b)。这种情况通常发生在图像模式(mode)不是RGB模式的时候。

可以在处理图像之前,将图像转换为RGB模式。

bash 复制代码
# 将图像转换为RGB模式
img = img.convert('RGB')

修改代码为:

bash 复制代码
# 导入Pillow库中的Image模块
from PIL import Image

# 打开名为"landscape.jpg"的图像文件
img = Image.open('img_1.png')

# 将图像转换为RGB模式
img = img.convert('RGB')

# 获取图像的宽度和高度
width, height = img.size
print("图像宽度:", width, "图像高度:", height)

# 遍历图像的每个像素点
for x in range(0, height):
    for y in range(0, width):
        # 获取当前像素点的红色(r)、绿色(g)、蓝色(b)通道的像素值
        (r, g, b) = img.getpixel((x, y))

        # 打印每个像素点的RGB值
        print("像素点 (x:", x, ", y:", y, ") 的RGB值: (R:", r, ", G:", g, ", B:", b, ")")

结果:

解决办法二:

修改传递参数即可,

将三个传递参数添加第四个d即可解决问题。

bash 复制代码
(r, g, b,d) = img.getpixel((x, y))

完整代码

bash 复制代码
# 导入Pillow库中的Image模块
from PIL import Image

# 打开名为"landscape.jpg"的图像文件
img = Image.open('img_1.png')

# 获取图像的宽度和高度
width, height = img.size
print("图像宽度:", width, "图像高度:", height)

# 遍历图像的每个像素点
for x in range(0, height):
    for y in range(0, width):
        # 获取当前像素点的红色(r)、绿色(g)、蓝色(b)通道的像素值
        (r, g, b,d) = img.getpixel((x, y))

        # 打印每个像素点的RGB值
        print("像素点 (x:", x, ", y:", y, ") 的RGB值: (R:", r, ", G:", g, ", B:", b, ")")

结果依旧

改变单个通道

首先使用Pillow库打开了名为"landscape.jpg"的图像文件。然后,我们获取了图像的宽度和高度,并创建了一个新的图像对象new_img,它具有相同的大小。接着,我们使用嵌套的循环遍历原始图像的每个像素点。

在每个像素点,我们使用img.getpixel((col, row))获取红、绿、蓝三个通道的像素值。然后,我们将原始图像的绿色通道的像素值增加了50,创建了一个新的颜色。这个新颜色包含了原始红色通道的值(r),绿色通道的值增加了50(g+50),和原始蓝色通道的值(b)。最后,我们使用new_img.putpixel((col, row), (r, g + 50, b))将修改后的像素值放入新图像对象中。

bash 复制代码
# 导入Pillow库中的Image模块
from PIL import Image

# 打开名为"landscape.jpg"的图像文件
img = Image.open('img_1.png')

# 获取图像的宽度和高度
width, height = img.size
print("原始图像宽度:", width, "图像高度:", height)

# 创建一个新的RGB模式的图像对象,具有相同的大小
new_img = Image.new('RGB', (width, height))

# 遍历原始图像的每个像素点
for row in range(0, height):
    for col in range(0, width):
        # 获取当前像素点的红色(r)、绿色(g)、蓝色(b)通道的像素值
        (r, g, b) = img.getpixel((col, row))

        # 修改绿色通道的像素值,增加50
        new_green = g + 50

        # 将修改后的像素值放入新图像对象中
        new_img.putpixel((col, row), (r, new_green, b))

# 将修改后的图像保存为"landscape_edited.png"文件
new_img.save("landscape_edited1.png")

# 打印提示信息
print("图像处理完成,并保存为landscape_edited.png")

报错依旧:

按照上述方法二选一即可解决报错问题,我用添加的方法二避免报错。

完整代码

bash 复制代码
# 导入Pillow库中的Image模块
from PIL import Image

# 打开名为"landscape.jpg"的图像文件
img = Image.open('img_1.png')

# 获取图像的宽度和高度
width, height = img.size
print("原始图像宽度:", width, "图像高度:", height)

# 创建一个新的RGB模式的图像对象,具有相同的大小
new_img = Image.new('RGB', (width, height))

# 遍历原始图像的每个像素点
for row in range(0, height):
    for col in range(0, width):
        # 获取当前像素点的红色(r)、绿色(g)、蓝色(b)通道的像素值
        (r, g, b,d) = img.getpixel((col, row))

        # 修改绿色通道的像素值,增加50
        new_green = g + 50

        # 将修改后的像素值放入新图像对象中
        new_img.putpixel((col, row), (r, new_green, b,d))

# 将修改后的图像保存为"landscape_edited.png"文件
new_img.save("landscape_edited1.png")

# 打印提示信息
print("图像处理完成,并保存为landscape_edited.png")

结果:

这里也放方法一的结果:

依然可以完成这样的结果。

黑白特效

为了实现基本的黑白特效,我们必须确保所有3个通道都具有相同的值。

让我们再次迭代每个像素,并计算三个通道像素值的平均值:

bash 复制代码
# 导入Pillow库中的Image模块
from PIL import Image

# 打开图片文件
img = Image.open('img_1.png')
# 将图像转换为RGB模式
img = img.convert('RGB')
# 获取图片的宽度和高度
width, height = img.size

# 输出图片的宽度和高度
print("原始图片大小:", width, height)

# 创建一张新的RGB模式的图片,大小与原始图片相同
new_img = Image.new('RGB', (width, height))

# 遍历原始图片的每个像素
for row in range(0, height):
    for col in range(0, width):
        # 获取当前像素点的RGB颜色值
        (r, g, b) = img.getpixel((col, row))

        # 计算RGB三个通道的平均值,将像素点转换为灰度
        avg = int((r + g + b) / 3)

        # 在新图片上设置当前像素点的颜色为灰度值,实现黑白效果
        new_img.putpixel((col, row), (avg, avg, avg))

# 将处理后的黑白图片保存为'landscape_black_and_white.jpg'
new_img.save("landscape_black_and_white.jpg")

# 输出处理后的图片保存成功的消息
print("黑白图片已保存为'landscape_black_and_white.jpg'")

颜色反转

看懂了上述代码,那么颜色反转的实现现在应该会很简单!

简单来说。我们的目标是将黑色像素(0,0,0)转换为白色像素(255,255,255)。

bash 复制代码
from PIL import Image

img = Image.open('img_1.png')
# 将图像转换为RGB模式
img = img.convert('RGB')
width, height = img.size
print(width, height)

new_img = Image.new('RGB', (width, height))
for row in range(0, height):
    for col in range(0, width):
        (r, g, b) = img.getpixel((col, row))

        inverted_pixel = (255 - r, 255-g, 255-b)
        new_img.putpixel((col, row), inverted_pixel)
new_img.save("landscape_edited.jpg")

将图像拆分成四个子部分

bash 复制代码
from PIL import Image

img = Image.open('img_1.png')
# 将图像转换为RGB模式
img = img.convert('RGB')
width, height = img.size
print(width, height)

new_img = Image.new('RGB', (width, height))

for row in range(0, height):
    for col in range(0, width):
        (r, g, b) = img.getpixel((col, row))

        if col < width * 0.25:
            (r, g, b) = (r, g, b)

        elif col < width * 0.5:
            avg = int((r + g + b) / 3)
            (r, g, b) = (avg, avg, avg)

        elif col < width * 0.75:
            (r, g, b) = (r, g + 50, b)

        else:
            (r, g, b) = (255 - r, 255 - g, 255 - b)

        new_img.putpixel((col, row), (r, g, b))

new_img.save("landscape_edited.jpg")

小结:
机器学习报错解决2------ValueError: too many values to unpack (expected 3)

这个文章里面的东西被参考,我用来做方法二,可以说有点用,但是方法一是最好的办法,避免方法二的传参问题,如果有参数传递错误,或者是版本问题导致库的传参问题,可以使用方法二

相关推荐
电子硬件笔记1 分钟前
Python语言编程导论第三章 编写程序
开发语言·python·编辑器
布谷歌1 分钟前
在java中实现c#的int.TryParse方法
java·开发语言·python·c#
cooldream20096 分钟前
当代 C++ 的三大技术支柱:资源管理、泛型编程与模块化体系的成熟演进
开发语言·c++
Aurora_eye15 分钟前
【花书第五章】汇报用
机器学习
Ulana16 分钟前
计算机基础10大高频考题解析
java·人工智能·算法
windfantasy199018 分钟前
NCT与GESP哪个更好?线上监考与线下考点的便利性对比
人工智能
执笔论英雄19 分钟前
【LORA】
人工智能
洲星河ZXH23 分钟前
Java,集合框架体系
开发语言·windows
宠..28 分钟前
写一个感染型病毒
开发语言·安全·安全性测试
wheelmouse778828 分钟前
一个优雅、通用、零侵入的 CSV 导出工具类(Java 实战)
java·开发语言