簡體   English   中英

如何在python中對圖像進行操作

[英]How to perform operations on images in python

我正在嘗試完成一個挑戰,我使用方程從其他圖像構建新圖像 (d)。 然后我必須得到圖像中的標志(d)。 給定的圖像是 a.png、b.png、c.png 和 y.png,它們可以在這里找到: https ://drive.google.com/drive/folders/1bZOm_0apr5ZmaRNf9R5UVIEmtMuYSphn?usp=sharing

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

我當前的代碼

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()

如果您將Pillow image轉換為numpy array或者您將使用OpenCVimageio加載圖像(並直接獲取numpy array ),那么您可以直接執行

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

結果:

不理想,但比使用您的代碼要好得多。

可能是overflow問題。 它可以創建具有 8 8bits值的數組,並且計算可以給出16bits 32bits32bits值,在每次計算中可以減少到 8 8bits

在此處輸入圖片說明

完整的工作代碼:

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()

編輯:

如果我使用OpenCV那么我會得到理想的結果

在此處輸入圖片說明

完整的工作代碼:

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()

編輯:

順便說一句: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()

順便提一句:

如果我使用程序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

我發現cv2.imread()c.png (這是JPG文件cv2.imread()提供的值與其他模塊幾乎沒有什么不同 - 我並不是說cv2BGR而不是RGB提供顏色 - 后來這給出了正確的結果。 可能cv2使用不同的 C 庫來讀取JPG

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM