简体   繁体   English

如何在python中对图像进行操作

[英]How to perform operations on images in python

I am trying to complete a challenge where i use an equation to construct a new image (d) from other images.我正在尝试完成一个挑战,我使用方程从其他图像构建新图像 (d)。 Then i must get the flag in the image (d).然后我必须得到图像中的标志(d)。 The given images are a.png, b.png c.png and y.png and they can be found here: https://drive.google.com/drive/folders/1bZOm_0apr5ZmaRNf9R5UVIEmtMuYSphn?usp=sharing给定的图像是 a.png、b.png、c.png 和 y.png,它们可以在这里找到: https ://drive.google.com/drive/folders/1bZOm_0apr5ZmaRNf9R5UVIEmtMuYSphn?usp=sharing

The equation: d = y - 21a - 3b + 41c等式:d = y - 21a - 3b + 41c

My current code我当前的代码

from PIL import Image

imagey = Image.open('y.png')
imagea = Image.open('a.png')
imageb = Image.open('b.png')
imagec = Image.open('c.png')
size = width, height = imagey.size

new = Image.new('RGB', size)

imgy = imagey.load()
imga = imagea.load()
imgb = imageb.load()
imgc = imagec.load()
data = new.load()

for x in range(width):
    for y in range(height):
        they = imgy[x, y]
        thea = imga[x, y]
        theb = imgb[x, y]
        thec = imgc[x, y]

        new_color = ((int(they[0])) & ~(int((21 * thea[0])) ^ int((3 * theb[0])) ^ int(~(41 * thec[0]))),
                     (int(they[1])) & ~(int((21 * thea[1])) ^ int((3 * theb[1])) ^ int(~(41 * thec[1]))),
                     (int(they[2])) & ~(int((21 * thea[2])) ^ int((3 * theb[2])) ^ int(~(41 * thec[2]))))
        data[x, y] = new_color

new.save('final.png')
new.show()

If you would convert Pillow image to numpy array or you would use OpenCV or imageio to load image (and get directly numpy array ) then you could do directly如果您将Pillow image转换为numpy array或者您将使用OpenCVimageio加载图像(并直接获取numpy array ),那么您可以直接执行

new = imagey - 21*imagea - 3*imageb + 41*imagec

Result:结果:

Not ideal but much better than with your code.不理想,但比使用您的代码要好得多。

It can be problem with overflow .可能是overflow问题。 It may create array with 8bits values and calculations can gives 16bits or 32bits values which can be reduced to 8bits in every calculation.它可以创建具有 8 8bits值的数组,并且计算可以给出16bits 32bits32bits值,在每次计算中可以减少到 8 8bits

在此处输入图片说明

Full working code:完整的工作代码:

import imageio

imagey = imageio.imread('y.png')
imagea = imageio.imread('a.png')
imageb = imageio.imread('b.png')
imagec = imageio.imread('c.png')

new = imagey - 21*imagea - 3*imageb + 41*imagec

imageio.imwrite('final.png', new)

# --- imageio doesn't have function to display it ---

import matplotlib.pyplot as plt

plt.imshow(new)
plt.show()

EDIT:编辑:

If I use OpenCV then I get ideal result如果我使用OpenCV那么我会得到理想的结果

在此处输入图片说明

Full working code:完整的工作代码:

import cv2

imagey = cv2.imread('y.png')
imagea = cv2.imread('a.png')
imageb = cv2.imread('b.png')
imagec = cv2.imread('c.png')

new = imagey - 21*imagea - 3*imageb + 41*imagec

cv2.imwrite('final.png', new)

# --- show window with image and wait for press any key ---

cv2.imshow('Image', new)
cv2.waitKey(0)
cv2.destroyAllWindows()

EDIT:编辑:

By the way: version which converts PIL Image to numpy array and later it converts back to PIL Image - but it gives the same result as imageio .顺便说一句:PIL Image转换为numpy array然后再转换回PIL Image - 但它给出的结果与imageio相同。

from PIL import Image
import numpy as np

imagey = Image.open('y.png')
imagea = Image.open('a.png')
imageb = Image.open('b.png')
imagec = Image.open('c.png')

arr_y = np.array(imagey)
arr_a = np.array(imagea)
arr_b = np.array(imageb)
arr_c = np.array(imagec)

arr_new = arr_y - 21*arr_a - 3*arr_b + 41*arr_c

new = Image.fromarray(arr_new)

new.save('final.png')
new.show()

BTW:顺便提一句:

If I check images on Linux using program file then it shows that b.png and c.png are JPEG , not PNG .如果我使用程序file在 Linux 上检查图像,那么它显示b.pngc.pngJPEG ,而不是PNG

$ file b.png

b.png: JPEG image data, JFIF standard 1.01, resolution (DPI), 
density 300x300, segment length 16, 
Exif Standard: [TIFF image data, big-endian, direntries=0], baseline, 
precision 8, 960x640, components 3

I found that cv2.imread() gives little different values for c.png (which is JPG file) then other modules - and I don't mean that cv2 gives colors in BGR instead of RGB - and later this gives correct result.我发现cv2.imread()c.png (这是JPG文件cv2.imread()提供的值与其他模块几乎没有什么不同 - 我并不是说cv2BGR而不是RGB提供颜色 - 后来这给出了正确的结果。 Probably cv2 uses different C library to read JPG .可能cv2使用不同的 C 库来读取JPG

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM