1. 程式人生 > >用Python幫你上馬,哪裡無碼打哪裡

用Python幫你上馬,哪裡無碼打哪裡

目錄
0 引言
1 環境
2 需求分析
3 程式碼實現
4 程式碼全景展示
5 後記

0 引言

所謂的畫素圖,就是對影象做一個顆粒化的效果,使其產生一種妙不可言的朦朧感。費話不多說,先來看一張效果圖。


▲效果圖

▲原圖

怎麼樣,效果還不錯吧?現在,我們用Python來實現這種畫素化的效果。

1 環境

作業系統:Windows

Python版本:3.7.3

2 需求分析

一個最簡單的實現思路,在開啟圖片後,把圖片分割成一些畫素塊,再對這些畫素塊中的影象資訊進行處理(修改影象中的RGB值)即可。

這裡我們使用Numpy庫和PIL庫來實現這個需求,後者用來影象的讀取與儲存,涉及到的所有影象處理動作均藉助Numpy來實現。

有關NumPy模組、PIL模組的介紹,可參考如下。

NumPy(Numerical Python) 是 Python 語言的一個擴充套件程式庫,支援大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式庫。

PIL(Python Imaging Library)是Python常用的影象處理庫,而Pillow是PIL的一個友好Fork,提供了了廣泛的檔案格式支援,強大的影象處理能力,主要包括影象儲存、影象顯示、格式轉換以及基本的影象處理操作等。

這兩個模組非Python內建,都屬於第三方模組,可直接採用如下方式進行安裝

pip install numpy
pip install Pillow

注意,要想使用PIL模組,是需要直接install Pillow模組的。

3 程式碼實現

首先匯入我們要用到的模組

import numpy as np
from PIL import Image

接下來,我們要處理圖片,首先得開啟一張圖片,如下

data = Image.open("P:\\Personal\\LuoShen.xpg")

然後把影象轉換化Numpy陣列進行下一步的處理

im1 = np.array(data)

這裡處理的核心思想,也很簡單,主要通過中間值的RGB,對所選範圍塊的RGB進行重新賦值。

im1[y:y + pixel, x:x + pixel] = im1[y + (pixel // 2)][x + (pixel // 2)]

這裡的x、y是分別指的我們影象的橫向、縱向畫素點的座標值、而pixel指的是我們要以多大的畫素塊,來處理這張影象,我們設定的單位畫素塊(Pixel數值)越小,生成的畫素圖越精確。

當然了,若單位畫素塊設定的太小,生成影象就看不出效果了,至於多大的數值合適,需要自行嘗試。不同尺寸的影象,要達到最佳的畫素化的顯示效果,所需要設定的單位畫素塊的大小也是不同的,實踐出真知。

我們需要影象的指定一個處理範圍,並對該範圍內的每一個座標(畫素)點進行畫素化的處理。

for y in range(Start_coordinate[1], End_coordinate[1], pixel):
    for x in range(Start_coordinate[0], End_coordinate[0], pixel):
        pass

在處理完成之後,我們再把Numpy陣列轉換回影象。

im2 = Image.fromarray(im1.astype(np.uint8))

最後展示出處理後的影象

im2.show()

4 程式碼全景展示

import numpy as np
from PIL import Image

def to_pixelBlock(pixel, Start_coordinate, End_coordinate):     
    '''     
    :param pixel: 單位畫素塊的元素大小        
    :param Start_coordinate: 處理的起始座標(畫素)點,元組形式      
    :param End_coordinate: 處理的終止座標(畫素)點,元組形式        
    :return:        
    通過中間值的RGB,對所選範圍塊的RGB進行重新賦值,設定的單位畫素塊(Pixel數值)越小,生成的畫素圖越精確
    '''
    # 讀取圖片,並由 PIL image 轉換為 NumPy array
    im1 = np.array(Image.open("P:\\Personal\\LuoShen.jpg"))


    # 遍歷所要處理範圍內的所有座標(畫素)點
    for y in range(Start_coordinate[1], End_coordinate[1], pixel):
        for x in range(Start_coordinate[0], End_coordinate[0], pixel):
            # 通過中間值的RGB,對所選範圍塊的RGB進行重新賦值
            im1[y:y + pixel, x:x + pixel] = im1[y + (pixel // 2)][x + (pixel // 2)]

    # 將NumPy array 轉換為 PIL image        
    im2 = Image.fromarray(im1.astype(np.uint8))
    # 展示處理後的影象
    im2.show()


if __name__ == '__main__':      
    # 設定好要處理的畫素範圍,並以多大的畫素塊來生成最終效果圖
    to_pixelBlock(10, (0, 0), (1280, 800)

5 後記

本文使用了PIL加上Numpy的配合,短短几行程式碼實現了影象畫素化的處理。當然這只是一種簡單地實現,要想實現更豐富的處理效果,還可以藉助CV2來實現。

好了,以上就是本篇全部內容。

公眾號「Python專欄」後臺回覆:「馬賽克」,獲取本文所涉及的完整程式碼