[OpenCV image implementation: Use Python to generate image special effects, error ValueError: too many values to unpack (expected 3)]

Article directory

    • summary
    • Read in image
    • Change a single channel
    • black and white special effects
    • color inversion
    • Split the image into four sub-parts

Summary

Python is a powerful programming language and one of the commonly used tools in the field of image processing. By using Python’s image processing libraries (such as Pillow, OpenCV, etc.), developers can achieve a variety of image special effects. These special effects include but are not limited to: filter effects (such as black and white, blur, sharpening, etc.), color conversion, edge detection, shape recognition, image synthesis, and augmented reality effects.

In Python, various algorithms and techniques can be used to process images, such as convolution operations, color space conversion, morphological operations, etc. Through these technologies, developers can create stunning image effects for beautifying photos, designing artworks, implementing computer vision applications, and more.

The process of image processing usually includes reading, processing and saving images. Python provides a simple and flexible API to make these operations easy. Developers can load images, perform various operations on them, and then save the processed images for subsequent use or display.

Read images

# Import the Image module in the Pillow library
from PIL import Image

# Open the image file named "landscape.jpg"
img = Image.open('./landscape.jpg')

# Get the width and height of the image
width, height = img.size
print("Image width:", width, "Image height:", height)

# Traverse each pixel of the image
for x in range(0, height):
    for y in range(0, width):
        # Get the pixel values of the red (r), green (g), and blue (b) channels of the current pixel
        (r, g, b) = img.getpixel((x, y))
        
        #Print the RGB value of each pixel
        print("RGB value of pixel (x:", x, ", y:", y, "): (R:", r, ", G:", g, \ ", B:", b, ")")

In the above code snippet, we have used Python’s Pillow library for image processing. First, we opened the sample image named “landscape.jpg” and obtained the width and height of the image. Next, we use a nested loop to iterate over all pixels of the image. At each pixel, we use the getpixel((x, y)) method to obtain the pixel values of the three channels of red (r), green (g), and blue (b).

Through this nested loop, we can print out the RGB value of each pixel in the image one by one to understand the composition of the image. This method can be used as the basis for image processing and provides basic data for subsequent image processing operations. Such operations allow us to gain a deeper understanding of the image and provide necessary information for subsequent image processing tasks.
Report an error;

D:\anaconda\envs\yolov5\python.exe E:\yolo project\Opencv-project-main\Opencv-project-main\CVZone\guangliu\33.py
Image width: 938 Image height: 613
Traceback (most recent call last):
  File "E:\yolo project\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


Solution one:
The error message indicates that in the line of code (r, g, b) = img.getpixel((x, y)), the value returned by getpixel((x, y)) is not the expected three pixel channel values (red, green , blue), but more values, so Python cannot correctly assign these values to (r, g, b). This situation usually occurs when the image mode (mode) is not RGB mode.
Images can be converted to RGB mode before processing them.

# Convert image to RGB mode
img = img.convert('RGB')

Modify the code to:

# Import the Image module in the Pillow library
from PIL import Image

# Open the image file named "landscape.jpg"
img = Image.open('img_1.png')

#Convert image to RGB mode
img = img.convert('RGB')

# Get the width and height of the image
width, height = img.size
print("Image width:", width, "Image height:", height)

# Traverse each pixel of the image
for x in range(0, height):
    for y in range(0, width):
        # Get the pixel values of the red (r), green (g), and blue (b) channels of the current pixel
        (r, g, b) = img.getpixel((x, y))

        #Print the RGB value of each pixel
        print("RGB value of pixel (x:", x, ", y:", y, "): (R:", r, ", G:", g, \ ", B:", b, ")")

result:

Solution two:
Just modify the parameters passed,
Adding a fourth d to the three passed parameters solves the problem.

(r, g, b,d) = img.getpixel((x, y))

Complete code

# Import the Image module in the Pillow library
from PIL import Image

# Open the image file named "landscape.jpg"
img = Image.open('img_1.png')

# Get the width and height of the image
width, height = img.size
print("Image width:", width, "Image height:", height)

# Traverse each pixel of the image
for x in range(0, height):
    for y in range(0, width):
        # Get the pixel values of the red (r), green (g), and blue (b) channels of the current pixel
        (r, g, b,d) = img.getpixel((x, y))

        #Print the RGB value of each pixel
        print("RGB value of pixel (x:", x, ", y:", y, "): (R:", r, ", G:", g, \ ", B:", b, ")")

The result remains the same

Change a single channel

First, the image file named “landscape.jpg” was opened using the Pillow library. We then get the width and height of the image and create a new image object new_img with the same size. Next, we use a nested loop to iterate over each pixel of the original image.

At each pixel, we use img.getpixel((col, row)) to obtain the pixel values of the three channels of red, green, and blue. We then created a new color by increasing the pixel value of the green channel of the original image by 50. This new color contains the original red channel value (r), the green channel value increased by 50 (g + 50), and the original blue channel value (b). Finally, we put the modified pixel values into the new image object using new_img.putpixel((col, row), (r, g + 50, b)).

# Import the Image module in the Pillow library
from PIL import Image

# Open the image file named "landscape.jpg"
img = Image.open('img_1.png')

# Get the width and height of the image
width, height = img.size
print("Original image width:", width, "Image height:", height)

# Create a new RGB mode image object with the same size
new_img = Image.new('RGB', (width, height))

# Traverse each pixel of the original image
for row in range(0, height):
    for col in range(0, width):
        # Get the pixel values of the red (r), green (g), and blue (b) channels of the current pixel
        (r, g, b) = img.getpixel((col, row))

        # Modify the pixel value of the green channel and increase it by 50
        new_green = g + 50

        #Put the modified pixel values into the new image object
        new_img.putpixel((col, row), (r, new_green, b))

# Save the modified image as "landscape_edited.png" file
new_img.save("landscape_edited1.png")

# Print prompt information
print("Image processing completed and saved as landscape_edited.png")

The error remains:

You can solve the error reporting problem by choosing one of the above methods. I used the added method two to avoid the error reporting.
Complete code

# Import the Image module in the Pillow library
from PIL import Image

# Open the image file named "landscape.jpg"
img = Image.open('img_1.png')

# Get the width and height of the image
width, height = img.size
print("Original image width:", width, "Image height:", height)

# Create a new RGB mode image object with the same size
new_img = Image.new('RGB', (width, height))

# Traverse each pixel of the original image
for row in range(0, height):
    for col in range(0, width):
        # Get the pixel values of the red (r), green (g), and blue (b) channels of the current pixel
        (r, g, b,d) = img.getpixel((col, row))

        # Modify the pixel value of the green channel and increase it by 50
        new_green = g + 50

        #Put the modified pixel values into the new image object
        new_img.putpixel((col, row), (r, new_green, b,d))

# Save the modified image as "landscape_edited.png" file
new_img.save("landscape_edited1.png")

# Print prompt information
print("Image processing completed and saved as landscape_edited.png")

result:

Here are also the results of method one:

Such results can still be achieved.

Black and white special effects

In order to achieve a basic black and white effect, we must ensure that all 3 channels have the same value.

Let’s iterate through each pixel again and calculate the average of the three channel pixel values:

# Import the Image module in the Pillow library
from PIL import Image

# Open image file
img = Image.open('img_1.png')
#Convert image to RGB mode
img = img.convert('RGB')
# Get the width and height of the image
width, height = img.size

# Output the width and height of the image
print("Original image size:", width, height)

#Create a new RGB mode image with the same size as the original image
new_img = Image.new('RGB', (width, height))

# Iterate through each pixel of the original image
for row in range(0, height):
    for col in range(0, width):
        # Get the RGB color value of the current pixel
        (r, g, b) = img.getpixel((col, row))

        # Calculate the average of the three RGB channels and convert the pixels into grayscale
        avg = int((r + g + b) / 3)

        # Set the color of the current pixel on the new picture to grayscale to achieve a black and white effect
        new_img.putpixel((col, row), (avg, avg, avg))

# Save the processed black and white image as 'landscape_black_and_white.jpg'
new_img.save("landscape_black_and_white.jpg")

# Output the message that the processed image was saved successfully
print("The black and white picture has been saved as'landscape_black_and_white.jpg'")

Color inversion

After understanding the above code, the implementation of color inversion should be very simple now!

simply put. Our goal is to convert black pixels (0, 0, 0) to white pixels (255, 255, 255).

from PIL import Image

img = Image.open('img_1.png')
#Convert image to RGB mode
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")

Split the image into four sub-parts

from PIL import Image

img = Image.open('img_1.png')
#Convert image to RGB mode
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")


summary:
Machine learning error solution 2–ValueError: too many values to unpack (expected 3)
The things in this article are referenced. I used method two, which can be said to be somewhat useful, but method one is the best way to avoid the parameter passing problem of method two. If there is a parameter passing error, or a version problem causes the library to fail For parameter passing problems, you can use method 2
.