【小林的OpenCV基礎課 4】滑動條什麼的

皆が待つようにする。小林嗓子發炎,昨晚肝到23點就肝不動了,大概是 上火了。

在上一話的結尾,我們提到了要使用神奇的工具(康娜醬默默地拿出了 滑鼠 滑動條 還有畫筆)

嗯,以小林的性格,絕對不會告訴你這一話要講簡單繪圖、滑鼠事件和滑動條的(づ ̄ 3 ̄)づ

畫畫什麼的 康娜醬最喜歡了

任務:教會康娜醬畫點、直線、矩形、圓形和寫字。

用到的函數:line,rectangle,circle和putText。

函數原型:

img=cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])

  • img:畫布
  • pt1,pt2:直線段起始點和終止點
  • color:線條顏色,BGR空間
  • thickness:線寬
  • linetype:線型,有cv.FILLED,cv.LINE_4, cv.LINE_8,cv.LINE_AA。

img=cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])

  • img:畫布
  • pt1,pt2:矩形的左上角和右下角
  • 剩餘參數同上

img=cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]])

  • center:圓心
  • radius:半徑
  • 其他參數同上。

img=cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])

哇,這個函數有好多的參數,其實呢,一般我們只關心一下幾個參數

  • img:畫布
  • text:要顯示的文字,字元串形式
  • org:文本框左下角的坐標
  • fontFace:字體,具體有哪些字體同學們可查閱API
  • fontScale:縮放倍數

下面,康娜醬 要 畫畫了!

import numpy as npimport cv2# 創建畫布img = np.zeros((512, 512, 3), np.uint8)img = cv2.line(img, (0, 0), (250, 250), (0, 0, 255), 2)img = cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)img = cv2.circle(img,(447,63), 63, (0,0,255), -1)# 字體變數font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(img,"OpenCV",(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)cv2.imshow("img",img)cv2.waitKey(0)cv2.destroyAllWindows()

康娜醬畫的

滑鼠 是什麼?

學過Java的同學知道,Java中有個叫偵聽器的東西,用來偵測事件。在OpenCV的滑鼠操作中也是靠滑鼠事件和回調函數完成的,滑鼠的移動、點擊左鍵或右鍵都會產生一個特定的事件,然後由回調函數完成我們想要實現的功能。

回調函數就像一個偵聽器,隨時偵測滑鼠的動作。

那麼有哪些滑鼠事件呢?我們可以在Python Console中輸入以下命令查看(注意環境哦):

>>> import cv2>>> events = [i for i in dir(cv2) if "EVENT" in i]>>> print events

任務:移動滑鼠並按下Ctrl鍵 畫 圓?

我們來寫一個回調函數,功能是 雙擊滑鼠左鍵畫一個圓,就叫draw_circle吧:

def draw_circle(event,x,y,flags,param): if event == cv2.EVENT_LBUTTONDBLCLK: cv2.circle(img,(x,y),100,(255,0,0),-1)

然後「激活」回調函數:

cv2.setMouseCallback("image",draw_circle)

這裡用到了setMouseCallback來「激活」回調函數,函數原型:

cv2.setMouseCallback(windowName, onMouse[, param])

  • windowname:窗口名,即我們要在哪個窗口使用滑鼠回調函數
  • onMouse:回調函數的函數名(不是字元串啊喂)
  • param:通常可選參數小林是不會講的,但是這裡提一下,這個參數可以被傳送到回調函數中哦,如果沒有需要傳遞的參數,這裡可以不寫,但在回調函數中一定要寫上

現在再來講下回調函數的flags和param參數:

  • flags:對應一系列事件,這些事件為,當event發生時是否按下了Ctrl、Shift或Alt鍵,對應的事件名可用上面命令行中的命令顯示
  • param:需要回傳的參數,亦可以元組和列表的形式傳入

好的,奉上完整代碼:

import cv2import numpy as np# 滑鼠回調函數def draw_circle(event,x,y,flags,param):# 滑鼠移動且按下Ctrl鍵 if event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_CTRLKEY:# 注意param的作用 print(param) cv2.circle(img,(x,y),100,(255,0,0),-1)# 創建畫布img = np.zeros((512,512,3), np.uint8)cv2.namedWindow("image")# 「激活」回調函數 需要傳遞的參數為字元串"I am the param"cv2.setMouseCallback("image",draw_circle,"I am the param")while(1): cv2.imshow("image",img) if cv2.waitKey(20) & 0xFF == 27: breakcv2.destroyAllWindows()

肝帝填坑:關於回調函數中的flags事件,由於我們的滑鼠回調函數是響應滑鼠事件的,而滑鼠事件中的點擊事件是在一瞬間完成的,所以若想搭配flags事件,就需要兩個事件同時發生(點擊的瞬間按下Ctrl鍵,同學們能做到嗎?)。

滑動條什麼的

來,跟小林一起念:Trackbar。(づ ̄ 3 ̄)づ

滑動條的實現類似上文滑鼠事件,也需要回調函數,相應的創建並「激活」函數為createTrackbar。

函數原型:

cv2.createTrackbar(trackbarName, windowName, value, count, onChange)

  • trackbarName:滑動條名字,運行時會顯示出來的
  • windowName:窗口名字
  • value:滑動條初始值
  • count:滑動條的調節範圍,0~count
  • onChange:回調函數名

若需要獲取滑動條當前值,則需要用函數getTrackbarPos(),函數原型:

cv2.getTrackbarPos(trackbarname, winname)

任務:嗯,還記得小林在【小林的OpenCV基礎課 3】的結尾嗎?下面小林寫一段RGB調色盤的代碼,幫助同學們理解RGB色彩空間。敲黑板了,OpenCV中是BGR而不是RGB!有關色彩空間的知識在這裡【小林的OpenCV基礎課 番外】色彩空間

import cv2import numpy as np# 滑動條回調函數 這裡啥也不做(才怪)def nothing(x): pass# 創建畫布img = np.zeros((300,512,3), np.uint8)cv2.namedWindow("image")# 創建並「激活」滑動條cv2.createTrackbar("R","image",0,255,nothing)cv2.createTrackbar("G","image",0,255,nothing)cv2.createTrackbar("B","image",0,255,nothing)# 用滑動條做一個二值開關switch = "0 : OFF
1 : ON"cv2.createTrackbar(switch, "image",0,1,nothing)while(1): cv2.imshow("image",img) k = cv2.waitKey(1) & 0xFF if k == 27: break# 獲取滑動條當前值 r = cv2.getTrackbarPos("R","image") g = cv2.getTrackbarPos("G","image") b = cv2.getTrackbarPos("B","image") s = cv2.getTrackbarPos(switch,"image")# 混合BGR通道 if s == 0: img[:] = 0 else: img[:] = [b,g,r]cv2.destroyAllWindows()

滑動條在我們後面的課程中用到的特別多,尤其是一些參數會直接使用滑動條修改。

這一話的示例代碼已經同步到了Github,在Class 2 GUI Core Features里。

最後的最後

如果喜歡小林的專欄,就收藏了吧!してください!


推薦閱讀:

用 Python 實現常用演算法和數據結構
Python練習第一題,在圖片上加入數字
機器學習之Python基礎(五) --協程,分散式

TAG:OpenCV | Python | 计算机视觉 |