python opencv鼠標畫點之cv2.drawMarker()函數(shù)
前言
這里所謂畫點的意思是指在單一像素點上畫一個標記符,而不是畫小圓點。使用的函數(shù)是cv2.drawMarker(img, position, color, ...)
關(guān)于鼠標回調(diào)函數(shù)的說明可以參考:opencv-python的鼠標交互操作
cv2.drawMarker()函數(shù)說明
參數(shù)說明
導入cv2后,通過help(cv2.drawMarker)可以看到函數(shù)的幫助文檔如下:
drawMarker(...) drawMarker(img, position, color[, markerType[, markerSize[, thickness[, line_type]]]]) -> img . @brief Draws a marker on a predefined position in an image. . . The function cv::drawMarker draws a marker on a given position in the image. For the moment several . marker types are supported, see #MarkerTypes for more information. . . @param img Image. . @param position The point where the crosshair is positioned. . @param color Line color. . @param markerType The specific type of marker you want to use, see #MarkerTypes . @param thickness Line thickness. . @param line_type Type of the line, See #LineTypes . @param markerSize The length of the marker axis [default = 20 pixels]
其中三個必選參數(shù):img, position, color,其他參數(shù)是可選。三個必選參數(shù)說明如下:
- img:底圖,uint8類型的ndarray,
- position:坐標,是一個包含兩個數(shù)字的tuple(必需是tuple),表示(x, y)
- color:顏色,是一個包含三個數(shù)字的tuple或list,表示(b, g, r)
其他參數(shù)說明如下:
- markerType:點的類型。取值0-6,有相應的宏定義與之對應,具體的可參考下面的一個表。
- markerSize:點的大小。大于0的整數(shù),必需是整數(shù)。實際輸入<=0的數(shù)字也可,但是估計程序里有判斷,<=0等同于1。默認值是20。
- thickness:點的線寬。必需是大于0的整數(shù),必需是整數(shù),不能小于0,默認值是1。
- line_type:線的類型??梢匀〉闹涤衏v2.LINE_4,cv2.LINE_8,cv2.LINE_AA。其中cv2.LINE_AA的AA表示抗鋸齒,線會更平滑。
markerType取值說明
數(shù)值 | 宏定義 | 說明 |
---|---|---|
0 | cv2.MARKER_CROSS | 十字線(橫豎兩根線) |
1 | cv2.MARKER_TILTED_CROSS | 交叉線(斜著兩根線) |
2 | cv2.MARKER_STAR | 米字線(橫豎加斜著共四根線) |
3 | cv2.MARKER_DIAMOND | 旋轉(zhuǎn)45度的正方形 |
4 | cv2.MARKER_SQUARE | 正方形 |
5 | cv2.MARKER_TRIANGLE_UP | 尖角向上的三角形 |
6 | cv2.MARKER_TRIANGLE_DOWN | 尖角向下的三角形 |
markerType示例
下面是一個簡單的畫點程序
# -*- coding: utf-8 -*- import cv2 import numpy as np if __name__ == '__main__': image = np.zeros((256, 256, 3), np.uint8) color = (0, 255, 0) cv2.drawMarker(image, (50, 50), color, markerType=0) cv2.drawMarker(image, (100, 50), color, markerType=1) cv2.drawMarker(image, (150, 50), color, markerType=2) cv2.drawMarker(image, (200, 50), color, markerType=3) cv2.drawMarker(image, (50, 100), color, markerType=4) cv2.drawMarker(image, (100, 100), color, markerType=5) cv2.drawMarker(image, (150, 100), color, markerType=6) cv2.namedWindow('marker_type', 1) cv2.imshow('marker_type', image) cv2.waitKey(0) cv2.destroyAllWindows()
請?zhí)貏e注意,opencv在調(diào)用這些畫圖函數(shù)后,image的內(nèi)容會被這些畫圖函數(shù)改變,也就是說,函數(shù)調(diào)用之后,我們就拿不回原始的image了,除非另外保存一份原始image的副本。在寫一些交互畫圖函數(shù)時,這個特性需要格外注意。
程序執(zhí)行結(jié)果如下。
利用鼠標回調(diào)函數(shù)交互式畫點
例1,簡單的例子
# -*- coding: utf-8 -*- import cv2 import numpy as np WIN_NAME = 'pick_points' def onmouse_pick_points(event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print('x = %d, y = %d' % (x, y)) cv2.drawMarker(param, (x, y), (0, 255, 0)) if __name__ == '__main__': image = np.zeros((256, 256, 3), np.uint8) cv2.namedWindow(WIN_NAME, 0) cv2.setMouseCallback(WIN_NAME, onmouse_pick_points, image) while True: cv2.imshow(WIN_NAME, image) key = cv2.waitKey(30) if key == 27: # ESC break cv2.destroyAllWindows()
上面程序中有幾個注意點:
- setMouseCallback()中的param參數(shù)我們傳遞了image進去,也就是說鼠標回調(diào)函數(shù)onmouse_pick_points()中的param就是image,畫點的操作在鼠標回調(diào)函數(shù)中,該參數(shù)在onmouse_pick_points中的變化可以保留到函數(shù)外,可以理解為C++的引用傳遞,或C語言的指針傳遞。
- 需要一個無限循環(huán)來刷新圖像。
- 無限循環(huán)的退出條件由鍵盤獲取,cv2.waitKey()用來獲取鍵盤的按鍵,當我們點ESC后就可以退出。
這里點了三次左鍵,終端輸出以下內(nèi)容:
x = 60, y = 55 x = 206, y = 113 x = 114, y = 192
并得到這樣一張圖像:
例2,刪除功能
如果需要刪除已經(jīng)畫了的點的功能,那么問題就變得略有些復雜了。
我們之前講過,opencv在畫了這些點之后,圖像的像素已經(jīng)事實上被改變了,想要緊緊通過當前圖像將其恢復原狀是不行的。所以為了實現(xiàn)刪除功能,我們需要備份一張原始圖像,一張用來對外顯示的圖像,以及一個由點坐標組成的list。
每次做刪除點的操作后,我們都使用原始圖像重置對外顯示的圖像,然后再把list中所有的點都重新畫在對外顯示的圖像上,就可以實現(xiàn)刪除點的效果。如果是增加點的操作,則不用重置圖像。
實現(xiàn)代碼如下:
下面代碼中,左鍵實現(xiàn)增加一個點的操作,右鍵依次刪除后面畫上的點。
# -*- coding: utf-8 -*- import cv2 import numpy as np WIN_NAME = 'pick_points' class DrawPoints(object): def __init__(self, image, color, marker_type=cv2.MARKER_CROSS, marker_size=20, thickness=1): """ Initialization of class DrawPoints Parameters ---------- image: ndarray source image. shape is [height, width, channels] color: tuple a tuple containing uint8 integers, designating B, G, R values, separately marker_type: int marker type, between [0, 6] marker_size: int marker size, >=1 thickness: int line thickness, >=1 """ self.original_image = image self.image_for_show = image.copy() self.color = color self.marker_type = marker_type self.marker_size = marker_size self.thickness = thickness self.pts = [] def append(self, x, y): """ add a point to points list Parameters ---------- x, y: int, int coordinate of a point """ self.pts.append((x, y)) def pop(self): """ pop a point from points list """ pt = () if self.pts: pt = self.pts.pop() return pt def reset_image(self): """ reset image_for_show using original image """ self.image_for_show = self.original_image.copy() def draw(self): """ draw points on image_for_show """ for pt in self.pts: cv2.drawMarker(self.image_for_show, pt, color=self.color, markerType=self.marker_type, markerSize=self.marker_size, thickness=self.thickness) def onmouse_pick_points(event, x, y, flags, draw_pts): if event == cv2.EVENT_LBUTTONDOWN: print('add: x = %d, y = %d' % (x, y)) draw_pts.append(x, y) draw_pts.draw() elif event == cv2.EVENT_RBUTTONDOWN: pt = draw_pts.pop() if pt: print('delete: x = %d, y = %d' % (pt[0], pt[1])) draw_pts.reset_image() draw_pts.draw() if __name__ == '__main__': image = np.zeros((256, 256, 3), np.uint8) draw_pts = DrawPoints(image, (0, 255, 0)) cv2.namedWindow(WIN_NAME, 0) cv2.setMouseCallback(WIN_NAME, onmouse_pick_points, draw_pts) while True: cv2.imshow(WIN_NAME, draw_pts.image_for_show) key = cv2.waitKey(30) if key == 27: # ESC break cv2.destroyAllWindows()
終端輸出如下:
add: x = 54, y = 51
add: x = 215, y = 81
add: x = 123, y = 121
add: x = 57, y = 197
add: x = 168, y = 210
delete: x = 168, y = 210
delete: x = 57, y = 197
得到的結(jié)果如下:
總結(jié)
到此這篇關(guān)于python opencv鼠標畫點之cv2.drawMarker()函數(shù)的文章就介紹到這了,更多相關(guān)opencv鼠標畫點cv2.drawMarker()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python語言實現(xiàn)將圖片轉(zhuǎn)化為html頁面
這篇文章主要介紹了Python實現(xiàn)將圖片轉(zhuǎn)化為html頁面,具有一定參考價值,需要的朋友可以了解下。2017-12-12利用Python將圖片批量轉(zhuǎn)化成素描圖的過程記錄
萬能的Python真的是除了不會生孩子,其他的還真不在話下,下面這篇文章主要給大家介紹了關(guān)于如何利用Python將圖片批量轉(zhuǎn)化成素描圖的相關(guān)資料,需要的朋友可以參考下2021-08-08Python?OpenCV實現(xiàn)簡單的顏色識別功能(對紅色和藍色識別并輸出)
Python?OpenCV可以用來進行顏色識別,可以通過讀取圖像的像素值,來判斷像素點的顏色,從而實現(xiàn)顏色識別,這篇文章主要給大家介紹了關(guān)于Python?OpenCV實現(xiàn)簡單的顏色識別功能(對紅色和藍色識別并輸出)的相關(guān)資料,需要的朋友可以參考下2023-12-12python連接打印機實現(xiàn)打印文檔、圖片、pdf文件等功能
這篇文章主要介紹了python連接打印機實現(xiàn)打印文檔、圖片、pdf文件等功能,需要的朋友可以參考下2020-02-02ORM Django 終端打印 SQL 語句實現(xiàn)解析
這篇文章主要介紹了ORM Django 終端打印 SQL 語句實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08Python+OpenCV圖像處理——圖像二值化的實現(xiàn)
這篇文章主要介紹了Python+OpenCV實現(xiàn)圖像二值化,幫助大家更好的利用python處理圖片,感興趣的朋友可以了解下2020-10-10