Python 影象處理 OpenCV (2):畫素處理與 Numpy 操作以及 Matplotlib 顯示影象
阿新 • • 發佈:2020-05-19
![](https://cdn.geekdigging.com/opencv/opencv_header.png)
前文傳送門:
[「Python 影象處理 OpenCV (1):入門」](https://www.geekdigging.com/2020/05/17/5513454552/)
## 普通操作
### 1. 讀取畫素
讀取畫素可以通過行座標和列座標來進行訪問,灰度影象直接返回灰度值,彩色影象則返回B、G、R三個分量。
需要注意的是, OpenCV 讀取影象是 BGR 儲存顯示。
灰度圖片讀取操作:
```python
import cv2 as cv
# 灰度影象讀取
gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE)
print(gray_img[20, 30])
# 顯示圖片
cv.imshow("gray_img", gray_img)
# 等待輸入
cv.waitKey()
cv.destroyAllWindows()
```
![](https://cdn.geekdigging.com/opencv/02/read_px1.png)
對於讀取灰度影象的畫素值,只會返回相應的灰度。
彩色影象讀取操作:
```python
import cv2 as cv
# 彩色影象讀取
color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
print(color_img[20, 30])
blue = color_img[20, 30, 0]
print(blue)
green = color_img[20, 30, 1]
print(green)
red = color_img[20, 30, 2]
print(red)
# 顯示圖片
cv.imshow("color_img", color_img)
# 等待輸入
cv.waitKey()
cv.destroyAllWindows()
# 列印結果
[ 3 2 236]
3
2
236
```
![](https://cdn.geekdigging.com/opencv/02/read_px2.png)
需要注意的是在獲取彩色圖片畫素時的第二個引數 1|2|3 的含義是獲取 BGR 三個通道的畫素。
### 2. 修改畫素
修改畫素時,直接對畫素賦值新畫素即可。
如果是灰度圖片,直接賦值即可。
如果是彩色圖片,則需依次給 BGR 三個通道的畫素賦值。
```python
import cv2 as cv
# 灰度影象讀取
gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE)
print(gray_img[20, 30])
# 畫素賦值
gray_img[20, 30] = 255
print(gray_img[20, 30])
# 列印結果
72
255
# 彩色影象讀取
color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
print(color_img[20, 30])
# 畫素依次賦值
color_img[20, 30, 0] = 255
color_img[20, 30, 1] = 255
color_img[20, 30, 2] = 255
print(color_img[20, 30])
# 列印結果
[ 3 2 236]
[255 255 255]
```
如果覺得依次對 BGR 三個通道賦值有些麻煩的話,也可以通過陣列直接對畫素點一次賦值:
```python
# 畫素一次賦值
color_img[20, 30] = [0, 0, 0]
print(color_img[20, 30])
# 列印結果
[0 0 0]
```
下面是對一個區域的畫素進行賦值,將這個區域的畫素全都賦值成為白色:
```python
import cv2 as cv
color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
color_img[50:100, 50:100] = [255, 255, 255]
cv.imshow("color_img", color_img)
cv.waitKey()
cv.destroyAllWindows()
```
![](https://cdn.geekdigging.com/opencv/02/read_px3.png)
## 使用 Numpy 操作
### 1. 讀取畫素
使用 Numpy 進行畫素讀取,呼叫方式如下:
```python
返回值 = 影象.item(位置引數)
```
讀取灰度影象和彩色影象如下:
```python
import cv2 as cv
# 讀取灰度影象
gray_img = cv.imread("maliao.jpg", cv.IMREAD_GRAYSCALE)
print(gray_img.item(20, 30))
# 列印結果
72
# 讀取彩色影象
color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
blue = color_img.item(20, 30, 0)
print(blue)
green = color_img.item(20, 30, 1)
print(green)
red = color_img.item(20, 30, 2)
print(red)
# 列印結果
3
2
236
```
### 2. 修改畫素
修改畫素需要使用到 Numpy 的 `itemset()` 方法,呼叫方式如下:
```python
影象.itemset(位置, 新值)
```
下面是我將 `[20, 30]` 這個修改為白色的示例:
```python
import cv2 as cv
# 讀取彩色影象
color_img = cv.imread("maliao.jpg", cv.IMREAD_COLOR)
print(color_img[20, 30])
color_img.itemset((20, 30, 0), 255)
color_img.itemset((20, 30, 1), 255)
color_img.itemset((20, 30, 2), 255)
print(color_img[20, 30])
# 輸出結果
[ 3 2 236]
[255 255 255]
```
> 注意:普通操作通常用於選擇陣列的區域,例如上面的示例中的選擇了 `[50:100, 50:100]` 這麼一個正方形。對於單個畫素訪問, Numpy 陣列方法 array.item() 和 array.itemset() 被認為更好。
## Matplotlib 顯示影象
我們可以通過 OpenCV 讀入影象,然後使用 Matplotlib 來進行影象顯示。
```python
import cv2 as cv
from matplotlib import pyplot as plt
img=cv.imread('maliao.jpg', cv.IMREAD_COLOR)
plt.imshow(img)
plt.show()
```
如果我們直接使用 Matplotlib 來顯示 OpenCV 讀入的影象,會得到下面這個藍色的馬里奧:
![](https://cdn.geekdigging.com/opencv/02/blue_maliao.png)
這是因為對於 OpenCV 的畫素是 BGR 順序,然而 Matplotlib 所遵循的是 RGB 順序。
解決的方案有很多種(迴圈畫素點的不算哈,這個太傻了),如下:
```python
import cv2 as cv
from matplotlib import pyplot as plt
img=cv.imread('maliao.jpg',cv.IMREAD_COLOR)
# method1
b,g,r=cv.split(img)
img2=cv.merge([r,g,b])
plt.imshow(img2)
plt.show()
# method2
img3=img[:,:,::-1]
plt.imshow(img3)
plt.show()
# method3
img4=cv.cvtColor(img, cv.COLOR_BGR2RGB)
plt.imshow(img4)
plt.show()
```
結果我就不貼了,這三種方法都可以完成 BGR 至 RGB 的轉換。
## 示例程式碼
如果有需要獲取原始碼的同學可以在公眾號回覆「OpenCV」進行獲取。
## 參考
https://blog.csdn.net/eastmount/article/details/82120114
http://woshic