天天看點

數字圖像處理python基礎 (一)python圖像處理基礎(一)

python圖像處理基礎(一)

寫在前面的話: 友善以後查文檔,且這篇文章會随着學習一直更(因為還有opencv還沒怎麼學,目前是一些基本的操作)。都是跟着學習資料鞏固的,隻供學習使用。

第一部分—— 圖像基本操作

縮略圖、截圖、部分變換、旋轉、圖像轉換為數組進行操作
  • 讀取圖檔及灰階圖
from PIL import Image #導入PIL庫的Image類
import matplotlib.pyplot as plt

pil_im = Image.open('G:/photo/innovation/1.jpg') #讀取圖像檔案
pil_im_gray = pil_im.convert('L')

plt.subplot(121)
plt.imshow(pil_im)
plt.subplot(122)
plt.imshow(pil_im_gray)
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)
縮略圖

thumbnail 或 resize

pil_im.thumbnail((128,128))
out= pil_im.resize((128,128))
           
截圖

(box is the crop rectangle, as a (left, upper, right, lower) tuple.)

box=(100,100,400,400)
region = pil_im.crop(box)
           
部分變換

transpose 之後 paste

region = region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)
數字圖像處理python基礎 (一)python圖像處理基礎(一)
旋轉

rotate() 傳度數即可

圖像轉換為數組進行操作

可以對數組進行任意的灰階變換後再轉換為圖像輸出

im = np.array(Image.open('G:/photo/innovation/1.jpg'))
print(im.shape, im.dtype)
pil_im = Image.fromarray(im)

           

第二部分—— 圖像基本處理

灰階直方圖、直方圖均衡、空間濾波、圖像基本變換、仿射變換
灰階直方圖

contour作用是繪制等高線, hist 注意 im.flatten()

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
# read image to array
im = np.array(Image.open('G:/photo/innovation/1.jpg').convert('L'))
# create a new figure
plt.figure()
# don’t use colors
plt.gray()
# show contours with origin upper left corner
plt.contour(im, origin='image')
plt.axis('equal')
plt.axis('off')
plt.figure()
plt.hist(im.flatten(),128)
plt.show()
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)
直方圖均衡

c ( I ) = 1 N ∗ ∑ I = 0 I h ( i ) = c ( I − 1 ) + 1 N ∗ h ( I ) c(I) = \frac{1}{N} * \sum_{I=0}^{I}{h(i)} = c(I - 1) + \frac{1}{N} *h(I) c(I)=N1​∗I=0∑I​h(i)=c(I−1)+N1​∗h(I)

我們要對圖像求直方圖,就需要先把圖像矩陣進行flatten操作,使之變為一維數組,然後再進行統計用reshape進行變換,實際上變換後還是二維數組,兩個方括号,是以隻能用 flatten.

  • cumsum(): 計算累計和
  • flatten(): 個人了解為合并清單
  • interp(): 線性插值函數
  • numpy.interp(x, xp, fp, left=None, right=None, period=None)
def histeq(im,nbr_bins=256):
    """ Histogram equalization of a grayscale image. """

    # get image histogram
    imhist,bins = histogram(im.flatten(),nbr_bins,normed=True) 
    # 計算所有像素值
    cdf = imhist.cumsum() # cumulative distribution function 
    # 得出第一個乘數
    cdf = 255 * cdf / cdf[-1] # normalize
    
    # use linear interpolation of cdf to find new pixel values
    im2 = np.interp(im.flatten(),bins[:-1],cdf) 
    
    return im2.reshape(im.shape), cdf
           
from PIL import Image 
import numpy as np
im = array(Image.open('G:/photo/innovation/1.jpg').convert('L')) 
im2,cdf = histeq(im)

plt.figure(figsize=(18,10))
plt.subplot(231)
plt.hist(im.flatten(),256)
plt.subplot(232)
plt.plot(range(256),cdf)
plt.subplot(233)
plt.hist(im2.flatten(),256)
plt.subplot(234)
plt.gray()
plt.imshow(im)
plt.subplot(236)
plt.imshow(im2)

plt.show()
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)
空間濾波
  • 高斯濾波 gaussian_filter
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import filters

im = np.array(Image.open('G:/photo/innovation/1.jpg').convert('L')) 
im2 = filters.gaussian_filter(im,5)
pil_im2 = Image.fromarray(uint8(im2))
plt.imshow(pil_im2)
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)
圖像幾何變換

SciPy庫中的ndimage包的相關函數實作幾何變換,ndimage.affine_transform

im = np.array(Image.open('G:/photo/innovation/1.jpg').convert('L'))
H = np.array([[1.4,0.05,-100],[0.05,1.5,-100],[0,0,1]])
im2 = ndimage.affine_transform(im,H[:2,:2],(H[0,2],H[1,2]))

plt.figure()
plt.gray()
plt.imshow(im2)
plt.show()
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)
仿射變換
  • 圖像的坐标變換通常為仿射變換,其保留了共線性與距離比例
    • 共線性:變換前在同一直線上的點變換後還在同一直線上。
    • 距離比例:變換前後直線上各點之間的距離的比例保持不變。
  • 仿射變換的一般形式

u = c 11 x + c 12 y + c 13 u = c_{11}x + c_{12}y + c_{13} u=c11​x+c12​y+c13​ v = c 21 x + c 22 y + c 23 v = c_{21}x + c_{22}y + c_{23} v=c21​x+c22​y+c23​

  • c 13 , c 23 c_{13}, c_{23} c13​,c23​控制平移
  • c 11 , c 12 , c 21 , c 22 c_{11}, c_{12}, c_{21}, c_{22} c11​,c12​,c21​,c22​控制縮放、旋轉和剪切

接下來将一張圖進行仿射變換後貼到另一張圖的指定位置

def Haffine_from_points(fp,tp):
    """ Find H, affine transformation, such that tp is affine transf of fp. """
    
    if fp.shape != tp.shape:
        raise RuntimeError('number of points do not match')
    
    '''
    當 np.diag(array) 中,
    array是一個1維數組時,結果形成一個以一維數組為對角線元素的矩陣
    array是一個二維矩陣時,結果輸出矩陣的對角線元素
    
    '''
    # condition points
    # --from points--
    m = np.mean(fp[:2], axis=1)
    maxstd = np.max(std(fp[:2], axis=1)) + 1e-9 
    C1 = np.diag([1/maxstd, 1/maxstd, 1]) 
    C1[0][2] = -m[0]/maxstd
    C1[1][2] = -m[1]/maxstd
    fp_cond = np.dot(C1,fp)
      
    # --to points--
    m = np.mean(tp[:2], axis=1)
    C2 = C1.copy() #must use same scaling for both point sets 
    C2[0][2] = -m[0]/maxstd
    C2[1][2] = -m[1]/maxstd
    tp_cond = np.dot(C2,tp)
    
    # conditioned points have mean zero, so translation is zero
    A = np.concatenate((fp_cond[:2],tp_cond[:2]), axis=0) 
    U,S,V = np.linalg.svd(A.T)

    # create B and C matrices as Hartley-Zisserman (2:nd ed) p 130.
    tmp = V[:2].T
    B = tmp[:2]
    C = tmp[2:4]
    
    '''
    vstack():堆棧數組垂直順序(行)
    hstack():堆棧數組水準順序(列)
    concatenate():連接配接沿現有軸的數組序列
    
    '''
    tmp2 = np.concatenate((dot(C,linalg.pinv(B)),zeros((2,1))), axis=1) 
    H = np.vstack((tmp2,[0,0,1]))
    # decondition
    H = dot(np.linalg.inv(C2),np.dot(H,C1)) 
    
    return H / H[2,2]
           
def image_in_image(im1,im2,tp):
    """ Put im1 in im2 with an affine transformation
    such that corners are as close to tp as possible.
    tp are homogeneous and counter-clockwise from top left. """
	
    # points to warp from
    m,n = im1.shape[:2]
    fp = np.array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])
    # compute affine transform and apply
    H = Haffine_from_points(tp,fp)

    im1_t = ndimage.affine_transform(im1,H[:2,:2], (H[0,2],H[1,2]),im2.shape[:2])
    alpha = (im1_t > 0)
    
    return (1-alpha)*im2 + alpha*im1_t
           
# example of affine warp of im1 onto im2
im1 = np.array(Image.open('G:/photo/innovation/1.jpg').convert('L'))
im2 = np.array(Image.open('G:/photo/innovation/3.jpg').convert('L'))

tp = array([[158,310,304,141],[76,98,253,218],[1,1,1,1]]) 
im3 = image_in_image(im1,im2,tp)
plt.figure()
plt.gray()
plt.imshow(im3)
plt.axis('equal')
plt.axis('off')
plt.show()
           
數字圖像處理python基礎 (一)python圖像處理基礎(一)