如何在windows配置python開發所需的opencv套件_pillow枕頭套件_matplotlib套件_戰勝這個亂世



大家好

本次要和教大家配置python版的opencv
和另外三種套件的基礎運用
主要原因在於課程作業有用到順便寫下一些經驗及分享

讓大家可以在這個亂世中求生存

然後分享一些python程式語法的定石


請先至下方兩個link分別下載
1. opencv3.2.0
https://github.com/opencv/opencv/releases/tag/3.2.0
2. python2.7.13
https://www.python.org/



首先目前opencv 最新版本已經出現至
3.2.0

http://opencv.org/releases.html


那基本上  3.1.0  和  3.2.0

他們所 support 的 python 版本皆為 2.7版的python

因此我們先使用  2.7 python做一些電腦視覺相關的開發教學


首先將你下載好的python 確認並添加  環境變數

兩個路徑



OK
在安裝opencv之前

這裡我用的是2.7.13

先將
cv2.pyd
複製到python安裝目錄Lib\site-packages下





嘗試打開 2.7.13的 command
輸入  import cv2 之後
出現錯誤



到終端機下
python -m pip install --upgrade numpy

更新 numpy 套件 (數學套件)


之後就能正常運行了


接著我們來利用pip套件安裝管理指令
新增幾項常用的套件
記得先下載pip 才能使用該指令
https://pypi.python.org/pypi/pip/

在這個亂世,若能多攜帶幾個幫助我們打仗的夥伴就會比較可靠
首先是影像(圖像)方面處裡的輔助套件庫
matplotlib
pillow



pip install matplotlib(記得numpy要先裝!!!)
https://matplotlib.org/


一套在python運行 Matlab 科學運算的套件庫
(Python 2D plotting library)
主要是做數學運算後的視覺呈現(資訊視覺化) 和 數學計算
裡面提供各式各樣繪製圖的方法
最常用的是  縮放、存取圖、影像顯示

pip install pillow
https://pillow.readthedocs.io/en/4.1.x/


Pillow 在此並非枕頭的含意,Python Imaging Library(PIL)
是一套python自帶圖像處裡的影像套件






下載完這些套件後

首先使用2.7.13該版開啟   pycharm

Numpy 基礎知識學習
矩陣的初始化

Numpy 矩陣初始化程式定石、矩陣屬性


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# -*- coding: utf-8 -*-
import numpy as np
#矩陣宣告及數值指定
print 'Numpy學習'
#一維線性
print '一維線性矩陣'
arrayLinear = np.array( [1,2,3,4,5,6,7]  )
print arrayLinear
print 'number of dim:' ,  arrayLinear.ndim
print 'shape:' , arrayLinear.shape
print 'size:' , arrayLinear.size
#二維平面3*3
arrayPlane = np.array([ [1,2,3] ,
                        [2,3,4] ,
                        [3,4,5] ])
print '二維平面矩陣'
print arrayPlane
print 'number of dim:' ,  arrayPlane.ndim
print 'shape:' , arrayPlane.shape
print 'size:' , arrayPlane.size

#三維立方體 2*4*3
arrayCube = np.array([
                       [
                          [21,32,65] ,
                          [78,94,76] ,
                          [79,44,65] ,
                          [89,54,73]
                       ] ,

                       [
                         [32,56,89] ,
                         [43,23,32] ,
                         [32,56,78] ,
                         [94,78,45]
                       ]
                     ])
print '三維立方體矩陣'
print arrayCube
print 'number of dim:' ,  arrayCube.ndim
print 'shape:' , arrayCube.shape
print 'size:' , arrayCube.size

示意圖


Numpy 矩陣之常用屬性

1.dim  矩陣維度
(在1D和2D可勉強說橫列有幾列  )
這裡牽涉到  python 列表 list的語法觀念
可參考  這篇教學學習 : My python_寒假特訓_8_列表的使用

在 python 中 列表(List)是可以放很多東西的地方
1.可以任意修改內部成員內容(權限極大)  2.以中括號包覆
而且列表中的成員  也可以是 一個 列表 !!!!!!
這裡都是進行矩陣運算的 列表應用
屬於   ---->   普通統一列表(成員都是列表型態)

2.shape 矩陣的
(對二維  橫列有幾列 , 直行有幾行)
(對三維  長寬高各多長多少成員?)

3.size 總共有多少元素
(對一維就直接是最後一個Index)
(對二維則是  列 * 行)
(對三維就是  長*寬*高)

一維數組(陣列)
宣告(指派數值)方式
#一維線性arrayLinear = np.array( [1,2,3,4,5,6,7]  )

印出來的時候 跟list不同
在於無 逗號 隔開!!


二維數組(陣列)
宣告(指派數值)方式
#二維平面3*3arrayPlane = np.array([ [1,2,3] ,                        [2,3,4] ,                        [3,4,5] ])


三維數組(陣列)
宣告(指派數值)方式
#三維立方體 2*4*3arrayCube = np.array([
                       [
                          [21,32,65] ,                          [78,94,76] ,                          [79,44,65] ,                          [89,54,73]
                       ] ,
                       [
                         [32,56,89] ,                         [43,23,32] ,                         [32,56,78] ,                         [94,78,45]
                       ]
                     ])

PS: 一些用語可能會需要顛倒了解
台灣:陣列    橫列直行
大陸:數組    橫行直列



Numpy 建全0、全1、全空 之矩陣  程式定石








Numpy 矩陣的成員型態指定   程式定石















opencv套件在python上的基礎活用

讀原彩圖圖像


讀圖像轉灰階


讀原彩圖圖像 指定參數寫法


讀灰階圖像  參數寫法



絕對路徑  vs 相對路徑(專案目錄下)




Python Opencv 圖像顯示 鍵盤控制 存圖 程式定石



# -*- coding: utf-8 -*-
import cv2
import numpy as np

#img = cv2.imread('man.jpg')
#img = cv2.imread('man.jpg',cv2.IMREAD_GRAYSCALE)
#img = cv2.imread('man.jpg',1)
img = cv2.imread('man.jpg',0)
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img)
key = cv2.waitKey(0)
#等待特定時間內是否有鍵盤按下,(時間以毫秒計算)返回ASCII值 、 若設置0則會無限等待鍵盤輸入
if key == 27:#wait for ESC key to exit
    cv2.destroyAllWindows()
elif key == ord('s'):#當我按下S鍵就存圖
    #cv2.imwrite('saveImg.png', img)
    cv2.imwrite("D:\\untitled\\graySave.jpg", img)
    cv2.destroyAllWindows()



Matplotlib套件在python上的基礎活用

我們先呈現出一張很完美的數學線性方程式圖
y = 2x + 1 的線段
x 從 -1 至 +1 共50個點
生成出一條直線


python Matplotlib 呈現特定線性方程圖形 程式定石
結合  numpy

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1,1,50)
#y = 2*x+1
y = -x**2
plt.plot(x,y)
plt.show()



那如果想要呈現一個  二次彎取開口朝上的取線
比方說
y = x^2


前面加負號 變朝下


接著我們來看看  figure視窗窗口的程式控制
比方說我們要擴充兩個視窗各自去顯示不同線性方程
就使用下方python程式的定石

python Matplotlib Figure 呈現多個圖形 程式定石

import matplotlib.pyplot as plt  # matplotlib.pyplot 太長  改叫成plt

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3,3,50)
y1 = 2*x+1
y2 = -x**2
plt.figure()
plt.plot(x,y1)

plt.figure()
plt.plot(x,y2)

plt.show()








改變 Figure 的大小(長寬) 及 編號 


變更方程線段呈現樣式及顏色
將預設線段藍色  改為紅色   粗度設置為1 虛線樣式



python Matplotlib 設置坐標軸 程式定石

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3,3,50)
y1 = 2*x+1
y2 = -x**2

plt.figure(num=3 , figsize=(4,2))
plt.plot(x,y2)
plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')

plt.xlim((-1,2))
plt.ylim((-2,3))

plt.xlabel('I am X')
plt.ylabel('I am Y')

plt.show()



python Matplotlib 設置坐標軸顯示點座標值範圍 程式定石


import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3,3,50)
y1 = 2*x+1
y2 = -x**2

plt.figure(num=3 , figsize=(4,2))
plt.plot(x,y2)
plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')

plt.xlim((-1,2))
plt.ylim((-2,3))
plt.xlabel('I am X')
plt.ylabel('I am Y')

new_ticks = np.linspace(-1,2,5)
print new_ticks
plt.xticks(new_ticks)

plt.show()




python Matplotlib 設置坐標軸特定數值對應Label顯示


# -*- coding: UTF-8 -*-
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3,3,50)
y1 = 2*x+1
y2 = -x**2

plt.figure(num=3 , figsize=(4,2))
plt.plot(x,y2)
plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')

plt.xlim((-1,2))
plt.ylim((-2,3))
plt.xlabel('I am X')
plt.ylabel('I am Y')

new_ticks = np.linspace(-1,2,5)
print new_ticks
plt.xticks(new_ticks)
plt.yticks([-2, -1, 0, 1.25, 3] ,
           ['really bad','bad','normal','good','very good'])

plt.show()



更詳細  Matplotlib 請參考
http://matplotlib.org/api/pyplot_api.html


python Matplotlib  結合 Opencv 
灰階圖像顯示 程式定石

# -*- coding: utf-8 -*-

import cv2

from matplotlib import pyplot as plt

img = cv2.imread('man.jpg' , 0)
plt.imshow(img , cmap='gray',interpolation='bicubic')
plt.xticks([]),plt.yticks([])
#to hide tick values on X and Y axis
plt.show()




matplotlib.pyplot.imshow(X,
                                          cmap=None,
                                          norm=None,
                                          aspect=None,
                                          interpolation=None,
                                          alpha=None,
                                          vmin=None, vmax=None,
                                          origin=None, extent=None,
                                          shape=None,
                                          filternorm=1, filterrad=4.0,
                                          imlim=None,
                                          resample=None,
                                          url=None, hold=None, data=None, **kwargs)

這裡用到的參數為

第一個影像矩陣
X : array_like, shape (n, m) or (n, m, 3) or (n, m, 4)
Display the image in X to current axes. X may be an array or a PIL image. If X is an array, it can have the following shapes and types:
  • MxN – values to be mapped (float or int)
  • MxNx3 – RGB (float or uint8)
  • MxNx4 – RGBA (float or uint8)

第二個 顏色型態
cmap : Colormap, optional, default: None
If None, default to rc image.cmap value. cmap is ignored if X is 3-D, directly specifying RGB(A) values.
第三個 內插參數
interpolation : string, optional, default: None
Acceptable values are ‘none’, ‘nearest’, ‘bilinear’, ‘bicubic’, ‘spline16’, ‘spline36’, ‘hanning’, ‘hamming’, ‘hermite’, ‘kaiser’, ‘quadric’, ‘catrom’, ‘gaussian’, ‘bessel’, ‘mitchell’, ‘sinc’, ‘lanczos’
If interpolation is None, default to rc image.interpolation. See also the filternorm and filterradparameters.  If interpolation is ‘none’, then no interpolation is performed on the Agg, ps and pdf backends. Other backends will fall back to ‘nearest’.
這裡 內插參數可接受的有
‘nearest’, ‘bilinear’, ‘bicubic’, ‘spline16’, ‘spline36’, ‘hanning’, ‘hamming’, ‘hermite’, ‘kaiser’, ‘quadric’, ‘catrom’, ‘gaussian’, ‘bessel’, ‘mitchell’, ‘sinc’, ‘lanczos’

這裡用的是  bicubic

一般  Cubic Interpolation
就是所謂的  「三次內插」
內插函數是許多個三次多項式。

 如果是  bilinear
Linear Interpolation
就是用  「線性內插」
內插函數是許多個一次多項式




參考 link :
http://www.csie.ntnu.edu.tw/~u91029/Interpolation.html












PS: Matplotlib 彩圖通道順序: RGB  /  opencv:BGR
ref link:
http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.imshow




這裡若直接用預設無參數設置的形式
 Matplotlib 去顯示彩圖
那會發覺顏色有點些許異常
主要原因就在於  我們是先用opencv 去 read 一張圖
這個圖   pixel 排序是以 BGR 的順序
但是顯示的時候剛好 Matplotlib 會用
RGB 剛好順序顛倒

這個時候我們可以使用opencv去做通道順序重新排序

opencv  : B->G->R
Matplotlib : R->G->B




通道重整程式 (方法一.)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding: utf-8 -*-

import cv2
from matplotlib import pyplot as plt

img = cv2.imread('man.jpg' )

#通道順序修正
#Step1.先分離通道
b,g,r = cv2.split(img)
#Step2.再合併通道
#img2 = cv2.merge((r,g,b))

#cv2.namedWindow('img2' , cv2.WINDOW_NORMAL)
#cv2.imshow('img2',img2)

#cv2.waitKey(0)

#Step2.再依照 Matplotlib 依序合併
img2 = cv2.merge( (r,g,b) )
plt.imshow(img2 ,interpolation='bilinear')
plt.xticks([]),plt.yticks([])
plt.show()

方法1效果




當然我們也可以透過 opencv 的色彩空間轉換方法
去幫我們調整

色彩空間轉換程式 (方法二.) 程式變得更簡短又直觀


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# -*- coding: utf-8 -*-

import cv2
from matplotlib import pyplot as plt

img = cv2.imread('man.jpg' )
img2 = cv2.cvtColor(img , cv2.COLOR_BAYER_BG2RGB)

plt.imshow(img2 ,interpolation='bilinear')
plt.xticks([]),plt.yticks([])
plt.show()

方法2效果




OpenCV 通道分割



# -*- coding: utf-8 -*-

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('man.jpg' )
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img)
b,g,r = cv2.split(img);
cv2.namedWindow('B' , cv2.WINDOW_NORMAL)
cv2.imshow('B',b)
cv2.namedWindow('G' , cv2.WINDOW_NORMAL)
cv2.imshow('G',g)
cv2.namedWindow('R' , cv2.WINDOW_NORMAL)
cv2.imshow('R',r)
cv2.waitKey(0)


OpenCV 特定顏色通道抽離 結合Numpy

抽離紅色通道

抽離綠色通道

抽離藍色通道


抽離綠色、紅色通道(只剩下藍色通道(色板)數值)

opencv 結合  numpy 程式
特定通道抽離  程式定石

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-

import cv2
import numpy as np
img = cv2.imread('man.jpg' )
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img)
#圖像複製
img2 = img.copy()
img3 = img.copy()
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img2)
#只留B 通道
img[ : , : , 1] = 0 #將 G 通道圖(index=1)通通設置為0
img[ : , : , 2] = 0 #將 R 通道圖(index=2)通通設置為0
cv2.namedWindow('GR channel dismiss' , cv2.WINDOW_NORMAL)
cv2.imshow('GR channel dismiss',img)
#只留R 通道
img2[ : , : , 0] = 0 #將 B 通道圖(index=0)通通設置為0
img2[ : , : , 1] = 0 #將 G 通道圖(index=1)通通設置為0
cv2.namedWindow('BG channel dismiss' , cv2.WINDOW_NORMAL)
cv2.imshow('BG channel dismiss',img2)
#只留G 通道
img3[ : , : , 0] = 0 #將 B 通道圖(index=0)通通設置為0
img3[ : , : , 2] = 0 #將 R 通道圖(index=2)通通設置為0
cv2.namedWindow('BR channel dismiss' , cv2.WINDOW_NORMAL)
cv2.imshow('BR channel dismiss',img3)

cv2.waitKey(0)


效果

原理 :

人的眼睛之所以可以看到東西甚至知道物體顏色是因為
眼睛上的視網膜具有感光細胞(可見波長:380~780nm)
會依據以下的波長去過濾顏色亮度程度
blue : 435.8 nm
green : 546.1nm
red : 700 nm


一般電子工業所製作出來的感光元件稱為
CCD (Charge-Coupled Device)  或
CMOS (Complemetary Metal-Oxide Semiconductor)
的感光晶片

在電腦硬體則是用  boolean 去做強弱程度判別
它的原理則是把光的強弱變更為 電流的大小 or 電壓的高低
用相機之所以能夠拍攝出彩色影像是因為
有在相機的感光元件前面罩上一個紅色、藍色、綠色的濾光鏡
然後讓環境中的光源只有某個位置能允許紅色光、綠色光、藍色光可進入
各自去取得紅、藍、綠光的強弱度
再去做後處裡 就可得到三張不同影像
之後做重疊就能生出  彩色影像!!!!!!!!


投影機、電腦螢幕 都是這樣的類似原理
灰階用8bit 表示亮度  256個階層
若彩色則是
8bit  Red 成分  ---> 256階層
8bit  Blue  成分 ---> 256階層
8bit  Green  成分 ---> 256階層

256 * 256 *256 = 2的24次方個色階層 = 1024 * 1024 * 1024

投影機在投射出光之前有三片濾光鏡去限制各個顏色成分要顯示的
亮度強弱
每三個為一個點(pixel) / 像素、畫素
用一個24bit來做一個pixel



通道分割及合併
cv.Merge(src0, src1, src2, src3, dst)  → None  不用指定變數承接

cv2.merge(mv[, dst]) → dst   要指定變數承接

Parameters:
  • mv – input array or vector of matrices to be merged; all the matrices in mv must have the same size and the same depth.
  • count – number of input matrices when mv is a plain C array; it must be greater than zero.
  • dst – output array of the same size and the same depth as mv[0]; The number of channels will be the total number of channels in the matrix array.


opencv 通道分割寫法
在  python 有兩種



寫法1.預設順序(不明確指定Index)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding: utf-8 -*-

import cv2

img = cv2.imread('man.jpg' )
#可調式視窗大小圖像顯示寫法
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img)
#通道分割寫法1. opencv 自帶寫法
b,g,r = cv2.split(img)

cv2.namedWindow('B' , cv2.WINDOW_NORMAL)
cv2.imshow('B',b)

cv2.namedWindow('G' , cv2.WINDOW_NORMAL)
cv2.imshow('G',g)

cv2.namedWindow('R' , cv2.WINDOW_NORMAL)
cv2.imshow('R',r)



cv2.waitKey(0)

寫法2.明確指定Index


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- coding: utf-8 -*-

import cv2

img = cv2.imread('man.jpg' )
#可調式視窗大小圖像顯示寫法
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img)
#通道分割寫法1. opencv 自帶寫法省略Index
#b,g,r = cv2.split(img)

#通道分割寫法2. opencv 寫法明確指定Index
b = cv2.split(img)[0]
g = cv2.split(img)[1]
r = cv2.split(img)[2]

cv2.namedWindow('B' , cv2.WINDOW_NORMAL)
cv2.imshow('B',b)

cv2.namedWindow('G' , cv2.WINDOW_NORMAL)
cv2.imshow('G',g)

cv2.namedWindow('R' , cv2.WINDOW_NORMAL)
cv2.imshow('R',r)

cv2.waitKey(0)



用 numpy 的陣列 通道分割寫法




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-

import cv2
import numpy as np
img = cv2.imread('man.jpg' )
#可調式視窗大小圖像顯示寫法
cv2.namedWindow('image' , cv2.WINDOW_NORMAL)
cv2.imshow('image' , img)
# Numpy 陣列寫法
b = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)
g = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)
r = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)

b[:,:]=img[:,:,0]
g[:,:]=img[:,:,1]
r[:,:]=img[:,:,2]

cv2.namedWindow('B' , cv2.WINDOW_NORMAL)
cv2.imshow('B',b)

cv2.namedWindow('G' , cv2.WINDOW_NORMAL)
cv2.imshow('G',g)

cv2.namedWindow('R' , cv2.WINDOW_NORMAL)
cv2.imshow('R',r)

cv2.waitKey(0)

首先
b = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)
g = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)
r = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)

這句是先利用  numpy 當中的 .zeros()  method
幫助我們做










參考Link:

周莫煩

How to create 3 dimensions matrix in numpy , like matlab a(:,:,:)
https://stackoverflow.com/questions/1696135/how-to-create-3-dimensions-matrix-in-numpy-like-matlab-a


周莫煩教學影片
https://www.youtube.com/watch?v=46EsDY8V6lQ&index=2&list=PLXO45tsB95cKiBRXYqNNCw8AUo6tYen3l#t=411.540722

pillow官方網站
https://pillow.readthedocs.io/en/4.1.x/handbook/tutorial.html

selenium官方網站
https://learngeb-ebook.readbook.tw/intro/selenium.html

matplotlib官方網站
https://matplotlib.org/examples/index.html


http://www.yaoguangkeji.com/a_Y3elwwAb.html



留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題