[英]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
或者您将使用OpenCV
或imageio
加载图像(并直接获取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
32bits
或32bits
值,在每次计算中可以减少到 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.png
和c.png
是JPEG
,而不是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()
提供的值与其他模块几乎没有什么不同 - 我并不是说cv2
以BGR
而不是RGB
提供颜色 - 后来这给出了正确的结果。 Probably cv2
uses different C library to read JPG
.可能cv2
使用不同的 C 库来读取JPG
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.