該系列文章是講解Python OpenCV圖像處理知識,前期主要講解圖像入門、OpenCV基礎用法,中期講解圖像處理的各種算法,包括圖像銳化算子、圖像增強技術、圖像分割等,後期結合深度學習研究圖像識別、圖像分類應用。希望文章對您有所幫助,如果有不足之處,還請海涵~
該系列在github所有原始碼:
前一篇文章介紹了Python圖像處理基礎知識,這篇文章將講解 OpenCV+Numpy 圖像處理基礎知識,包括讀取像素和修改像素。知識點如下:
一.傳統讀取像素方法
二.傳統修改像素方法
三.Numpy讀取像素方法
四.Numpy修改像素方法
五.幾何圖形繪製
學Python近八年,認識了很多大佬和朋友,感恩。由於在外求學且需要養娃,故在CSDN設置成了最低價收費專欄,覺得不錯的可以購買抬愛;但作者的本意是幫助更多初學者入門,因此在github開源了所有代碼,也在公眾號同步更新。深知自己很菜,得拼命努力前行,編程也沒有什麼捷徑,幹就對了。希望未來能更透徹學習和撰寫文章,同時非常感謝參考文獻中的大佬們的文章和分享,共勉。
- https://blog.csdn.net/eastmount
一.傳統讀取像素方法1.灰度圖像,返回灰度值
返回值=圖像(位置參數),例:p = img[88,142] print(p)
# -*- coding:utf-8 -*-
import cv2
#讀取圖片
img = cv2.imread("picture.bmp", cv2.IMREAD_UNCHANGED)
#灰度圖像
p = img[88, 142]
print(p)
#顯示圖像
cv2.imshow("Demo", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
#寫入圖像
cv2.imwrite("testyxz.jpg", img)
輸出結果如下所示:[131 131 131],由於該圖是24位BMP,B=G=R輸出三個相同結果,有的圖像僅有一個像素點則輸出一個值。
2.BGR圖像,返回值為B、G、R的值
例:
b = img[78, 125, 0] print(b)
g = img[78, 125, 1] print(g)
r = img[78,125, 2] print(r)
# -*- coding:utf-8 -*-
import cv2
#讀取圖片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#BGR圖像
b = img[78, 125, 0]
print(b)
g = img[78, 125, 1]
print(g)
r = img[78, 125, 2]
print(r)
#方法二
bgr = img[78, 125]
print(bgr)
#顯示圖像
cv2.imshow("Demo", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
#寫入圖像
cv2.imwrite("testyxz.jpg", img)
輸出像素和圖像如下所示:
二.傳統修改像素方法1.修改單個像素值
BGR圖像可以通過位置參數直接訪問像素值並進行修改,輸出結果如下所示:
# -*- coding:utf-8 -*-
import cv2
#讀取圖片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#BGR圖像
print(img[78, 125, 0])
print(img[78, 125, 1])
print(img[78, 125, 2])
#修改像素
img[78, 125, 0] = 255
img[78, 125, 1] = 255
img[78, 125, 2] =255
print(img[78, 125])
img[78, 125] = [10, 10, 10]
print(img[78, 125, 0])
print(img[78, 125, 1])
print(img[78, 125, 2])
#方法二
print(img[78, 125])
img[78, 125] = [10, 10, 10]
print(img[78, 125])
輸出結果如下所示,通過兩種方法分別將B、G、R像素值修改為255和0。
155
104
61
255
255
255
[255 255 255]
[10 10 10]
2.修改區域像素
通過訪問圖像數組的位置區域實現區域像素修改,比如 [100:150,400:500] 是訪問第100到150行,400到500列的區域,再對該區域像素進行修改。代碼如下所示:
# -*- coding:utf-8 -*-
import cv2
#讀取圖片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#BGR圖像
img[100:150, 400:500] = [255, 255, 0]
#顯示圖像
cv2.imshow("Demo", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
#寫入圖像
cv2.imwrite("testyxz.jpg", img)
輸出結果如下所示,[255, 255, 0]是淺藍色。
三.Numpy讀取像素方法使用Numpy進行像素讀取,調用方式如下:
# -*- coding:utf-8 -*-
import cv2
import numpy
#讀取圖片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#Numpy讀取像素
blue = img.item(78, 100, 0)
green = img.item(78, 100, 1)
red = img.item(78, 100, 2)
print(blue)
print(green)
print(red)
#顯示圖像
cv2.imshow("Demo", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如下,注意OpenCV讀取圖像通道是BGR,也可以轉換成RGB在進行處理。
四.Numpy修改像素方法使用Numpy的itemset函數修改像素,調用方式如下:
例如:img.itemset((88,99), 255)
# -*- coding:utf-8 -*-
import cv2
import numpy
#讀取圖片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#Numpy讀取像素
print(img.item(78, 100, 0))
print(img.item(78, 100, 1))
print(img.item(78, 100, 2))
img.itemset((78, 100, 0), 100)
img.itemset((78, 100, 1), 100)
img.itemset((78, 100, 2), 100)
print(img.item(78, 100, 0))
print(img.item(78, 100, 1))
print(img.item(78, 100, 2))
輸出結果如下:
也可以同時輸出B、G、R三個值,核心代碼如下:
print(img[78, 78])
img.itemset((78, 78, 0), 0)
img.itemset((78, 78, 1), 0)
img.itemset((78, 78, 2), 0)
print(img[78, 78])
#[155 104 61]
#[0 0 0]
本小節主要講解OpenCV中幾何圖形的繪製方法,包括:
cv2.line()
cv2.circle()
cv2.rectangle()
cv2.ellipse()
cv2.polylines()
cv2.putText()
1.繪製直線在OpenCV中,繪製直線需要獲取直線的起點和終點坐標,調用cv2.line()函數實現該功能。該函數原型如下所示:
img = line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
– img表示需要繪製的那幅圖像
– pt1表示線段第一個點的坐標
– pt2表示線段第二個點的坐標
– color表示線條顏色,需要傳入一個RGB元組,如(255,0,0)代表藍色
– thickness表示線條粗細
– lineType表示線條的類型
– shift表示點坐標中的小數位數
下面的代碼是繪製一條直線,通過np.zeros()創建一幅黑色圖像,接著調用cv2.line()繪製直線,參數包括起始坐標和顏色、粗細。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製直線
cv2.line(img, (0,0), (255,255), (55,255,155), 5)
#顯示圖像
cv2.imshow("line", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示,從坐標(0,0)到(255,255)繪製一條直線,其直線顏色為(55,255,155),粗細為5。
基本線條的繪製方法掌握之後,我們能進行簡單的變化,比如下面的代碼增加了一個簡單循環,將圖形繪製成了四部分。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製直線
i = 0
while i<255:
cv2.line(img, (0,i), (255,255-i), (55,255,155), 5)
i = i + 1
#顯示圖像
cv2.imshow("line", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示。
2.繪製矩形在OpenCV中,繪製矩形通過cv2.rectangle()函數實現,該函數原型如下所示:
img = rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
– img表示需要繪製的那幅圖像
– pt1表示矩形的左上角位置坐標
– pt2表示矩形的右下角位置坐標
– color表示矩形的顏色
– thickness表示邊框的粗細
– lineType表示線條的類型
– shift表示點坐標中的小數位數
下面的代碼是繪製一個矩形,通過np.zeros()創建一幅黑色圖像,接著調用cv2.rectangle()繪製矩形。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製矩形
cv2.rectangle(img, (20,20), (150,250), (255,0,0), 2)
#顯示圖像
cv2.imshow("rectangle", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖,從左上角坐標為(20,20),右下角坐標為(150,250),繪製的矩形顏色為藍色(255,0,0),粗細為2。
3.繪製圓形在OpenCV中,繪製矩形通過cv2.rectangle()函數實現,該函數原型如下所示:
img = circle(img, center, radius, color[, thickness[, lineType[, shift]]])
– img表示需要繪製圓的圖像
– center表示圓心坐標
– radius表示圓的半徑
– color表示圓的顏色
– thickness如果為正值,表示圓輪廓的厚度;負厚度表示要繪製一個填充圓
– lineType表示圓的邊界類型
– shift表示中心坐標和半徑值中的小數位數
下面的代碼是繪製一個圓形。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製圓形
cv2.circle(img, (100,100), 50, (255,255,0), -1)
#顯示圖像
cv2.imshow("circle", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示,它在圓形為(100,100)的位置,繪製了一個半徑為50,顏色為(255,255,0)、粗細為4的圓。
注意,如果將粗細設置為「-1」,則繪製的圓為實心,如圖所示。
4.繪製橢圓在OpenCV中,繪製橢圓比較複雜,要多輸入幾個參數,如中心點的位置坐標,長軸和短軸的長度,橢圓沿逆時針方向旋轉的角度等。cv2.ellipse()函數原型如下所示:
img = ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]])
– img表示需要繪製橢圓的圖像
– center表示橢圓圓心坐標
– axes表示軸的長度(短半徑和長半徑)
– angle表示偏轉的角度(逆時針旋轉)
– startAngle表示圓弧起始角的角度(逆時針旋轉)
– endAngle表示圓弧終結角的角度(逆時針旋轉)
– color表示線條的顏色
– thickness如果為正值,表示橢圓輪廓的厚度;負值表示要繪製一個填充橢圓
– lineType表示圓的邊界類型
– shift表示中心坐標和軸值中的小數位數
下面是繪製一個橢圓的代碼。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製橢圓
#橢圓中心(120,100) 長軸和短軸為(100,50)
#偏轉角度為20
#圓弧起始角的角度0 圓弧終結角的角度360
#顏色(255,0,255) 線條粗細2
cv2.ellipse(img, (120, 100), (100, 50), 20, 0, 360, (255, 0, 255), 2)
#顯示圖像
cv2.imshow("ellipse", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示,其橢圓中心為(120,100),長軸為100,短軸為50,偏轉角度為20,圓弧起始角的角度為0,圓弧終結角的角度為360,表示一個完整的橢圓。繪製的顏色為(255,0,255),粗細為2。
下面的代碼是繪製一個實心橢圓。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製橢圓
cv2.ellipse(img, (120, 120), (120, 80), 40, 0, 360, (255, 0, 255), -1)
#顯示圖像
cv2.imshow("ellipse", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
繪製如圖所示的圖形。
5.繪製多邊形在OpenCV中,調用cv2.polylines()函數繪製多邊形,它需要指定每個頂點的坐標,通過這些點構建多邊形,其函數原型如下所示:
img = polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]])
– img表示需要繪製的圖像
– center表示多邊形曲線陣列
– isClosed表示繪製的多邊形是否閉合,False表示不閉合
– color表示線條的顏色
– thickness表示線條粗細
– lineType表示邊界類型
– shift表示頂點坐標中的小數位數
下面是繪製一個多邊形的代碼。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製多邊形
pts = np.array([[10,80], [120,80], [120,200], [30,250]])
cv2.polylines(img, [pts], True, (255, 255, 255), 5)
#顯示圖像
cv2.imshow("ellipse", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示,繪製的多邊形為白色的閉合圖形。
下面的代碼是繪製一個五角星多邊形。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((512,512,3), np.uint8)
#繪製多邊形
pts = np.array([[50, 190], [380, 420], [255, 50], [120, 420], [450, 190]])
cv2.polylines(img, [pts], True, (0, 255, 255), 10)
#顯示圖像
cv2.imshow("ellipse", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示,它將五個頂點左邊分別連接起來,構成了一個黃色的五角星。
6.繪製文字在OpenCV中,調用cv2.putText()函數添加對應的文字,其函數原型如下所示:
img = putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])
– img表示要繪製的圖像
– text表示要繪製的文字
– org表示要繪製的位置,圖像中文本字符串的左下角
– fontFace表示字體類型,具體查看see cv::HersheyFonts
– fontScale表示字體的大小,計算為比例因子乘以字體特定的基本大小
– color表示字體的顏色
– thickness表示字體的粗細
– lineType表示邊界類型
– bottomLeftOrigin如果為真,則圖像數據原點位於左下角,否則它在左上角
下面是繪製文字的代碼。
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#創建黑色圖像
img = np.zeros((256,256,3), np.uint8)
#繪製文字
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, 'I love Python!!!',
(10, 100), font, 0.6, (255, 255, 0), 2)
#顯示圖像
cv2.imshow("polylines", img)
#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出結果如圖所示,繪製的文字為「I love Python!!!」。
四.總結寫到這裡,這篇毒基礎性文章就介紹結束了。希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵。本文首發於CSDN專欄,為了幫助更多同學故在公眾號同步更新,一起加油!
一.傳統讀取像素方法
二.傳統修改像素方法
三.Numpy讀取像素方法
四.Numpy修改像素方法
五.幾何圖形繪製
學Python近八年,認識了很多大佬和朋友,希望大家一起進步,作者也會繼續深入學習並分享Python相關知識。由於在外求學且需要養娃,故在CSDN設置成了最低價收費專欄,覺得不錯的可以購買;但作者的本意是幫助更多初學者入門,因此在github開源了所有代碼,也在公眾號同步更新。深知自己很菜,得拼命努力前行,編程也沒有什麼捷徑,幹就對了。希望未來能更透徹撰寫相關文章,同時非常感謝參考文獻中的大佬們的文章和分享,砥礪前行。
前文回顧(下面的超連結可以點擊喔):
2020年新開的「娜璋AI安全之家」,主要圍繞Python大數據分析、網絡空間安全、人工智慧、Web滲透及攻防技術進行講解,同時分享CCF、SCI、南核北核論文的算法實現。娜璋之家會更加系統,並重構作者的所有文章,從零講解Python和安全,寫了近十年文章,真心想把自己所學所感所做分享出來,還請各位多多指教,真誠邀請您的關注!謝謝。2021年繼續加油!
(By:Eastmount 2021-02-08 夜於貴陽)
參考文獻:
[1] 羅子江. Python中的圖像處理[M]. 科學出版社,2020.
[2] https://blog.csdn.net/eastmount/category_9278090.html
[3] 岡薩雷斯. 數字圖像處理(第3版)[M]. 電子工業出版社,2013.
[4] 阮秋琦. 數字圖像處理學(第3版)[M]. 電子工業出版社,2008.
[5]毛星雲,冷雪飛. OpenCV3編程入門[M]. 電子工業出版社,2015.
[6]張錚. 數字圖像處理與機器視覺——Visual C++與Matlab實現.
[6]網易雲課堂_高登教育. Python+OpenCV圖像處理