Python3 用PIL處理圖像(二)——將圖片裝換成素描

今兒一朋友發了一張我的照片,經過了處理,轉換成素描照了,隨後又發了一段代碼給我,這個其實說新奇也不是太新奇,但是也挺有意思的,那我們就來分析一下這段代碼,看看是如何將一張圖片轉換成素描圖的;

我們先來看一下發給我的代碼是怎麼樣的:

from PIL import Image,ImageFilter,ImageOps

img = Image.open("蘋果.jpg")

def dodge(a,b,alpha):
    return min(int(a*255/(256-b*alpha)),255)

def draw(img,blur=10,alpha=1.0):
    img1 = img.convert('L')

    img2 = img1.copy()
    img2 = ImageOps.invert(img2)

    for i in range(blur):
        img2 = img2.filter(ImageFilter.BLUR)

    width,height = img1.size
    for x in range(width):
        for y in range(height):
            a = img1.getpixel((x,y))
            b = img2.getpixel((x,y))
            img1.putpixel((x,y),dodge(a,b,alpha))

    img1.save("素描.jpg")

draw(img)

OK,我們首先來總結一下,要實現圖片到素描的轉化,有哪些步驟:

  1. 打開目標圖片
  2. 因爲素描是黑白的,所以我們要轉換成灰度模式
  3. 對像素點進行處理
  4. 保存

那麼接下來,我們就一點一點來實現:

  1. 打開目標圖片
    from PIL import Image
    
    image = Image.open('人.jpg')
    
    image.show()
  2. 轉換成灰度模式
    from PIL import Image
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    image.show()
  3. 我們需要複製一層,然後將其反色,方便我們後面對照片進行處理
    from PIL import Image,ImageOps
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    
    image2 = image.copy()    # 複製一層
    image2 = ImageOps.invert(image2)    # 將圖片反相
    image2.show()

    我們發現,現在與之前相比,黑的變成白的,白的變成黑的了,通過 Python3 用PIL處理圖像(一)——PIL的基礎運用 應該知道,灰度模式就是8位的黑白照片,其中8位就是 0-255級別的黑白變化,我們後面可以看見,上圖和本圖同一個像素點位置的顏色值相加剛好是255

  4. 對image2添加模糊濾鏡
    from PIL import Image,ImageOps,ImageFilter
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    
    image2 = image.copy()
    image2 = ImageOps.invert(image2)
    
    for i in range(10):
        image2 = image2.filter(ImageFilter.BLUR)
    
    image2.show()

    會發現這裏用了循環,說明我們添加了10層濾鏡,這裏關於添加濾鏡次數對最後效果的影響,這裏能說的是,次數越多,最後素描的陰影效果就越強;

  5. 遍歷每個像素點,改變其顏色
    from PIL import Image,ImageOps,ImageFilter
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    
    image2 = image.copy()
    image2 = ImageOps.invert(image2)
    
    for i in range(10):
        image2 = image2.filter(ImageFilter.BLUR)
    
    width,height = image.size    # 獲得圖片的長和寬
    for x in range(width):       # 遍歷圖片的每一個像素點
        for y in range(height):
            a = image.getpixel((x,y))    # 獲取像素點的值
            b = image2.getpixel((x,y))
            image.putpixel((x,y),min(int(a*255/(256-b)),255))
            # image.putpixel(位置,值)函數就是用來修改像素點的值的
            # 其中 a*255/(256-b) 這個公式爲什麼出來之後就能夠達到素描的效果,恕我還沒有研究明白
            # 至於說這裏爲什麼還要用min()函數,這是因爲我們才計算過程中,可能會超過255,而我們最大值就是255
    
    image.show()

    我們發現現在的效果已經出來了,這裏是主要的實現,我們需要好好掰扯掰扯;

    這裏把每個像素點的處理後的值都顯示出來了,大家可以看到,同一個像素點反相之後和反色之前相加一直爲255;
    至於最後一個一直是在255左右變化,恕我沒整明白;

  6. 最後將圖片保存,完工!

我們看下,模糊濾鏡對最後效果的影響:

從左到右,分別添加了1、10、20、30次濾鏡,其效果就像輪廓和上色的差別,大家有興趣可以修改參數好好試一下;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章