python opencv鼠標(biāo)畫(huà)點(diǎn)之cv2.drawMarker()函數(shù)
前言
這里所謂畫(huà)點(diǎn)的意思是指在單一像素點(diǎn)上畫(huà)一個(gè)標(biāo)記符,而不是畫(huà)小圓點(diǎn)。使用的函數(shù)是cv2.drawMarker(img, position, color, ...)
關(guān)于鼠標(biāo)回調(diào)函數(shù)的說(shuō)明可以參考:opencv-python的鼠標(biāo)交互操作
cv2.drawMarker()函數(shù)說(shuō)明
參數(shù)說(shuō)明
導(dǎo)入cv2后,通過(guò)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]
其中三個(gè)必選參數(shù):img, position, color,其他參數(shù)是可選。三個(gè)必選參數(shù)說(shuō)明如下:
- img:底圖,uint8類型的ndarray,
- position:坐標(biāo),是一個(gè)包含兩個(gè)數(shù)字的tuple(必需是tuple),表示(x, y)
- color:顏色,是一個(gè)包含三個(gè)數(shù)字的tuple或list,表示(b, g, r)
其他參數(shù)說(shuō)明如下:
- markerType:點(diǎn)的類型。取值0-6,有相應(yīng)的宏定義與之對(duì)應(yīng),具體的可參考下面的一個(gè)表。
- markerSize:點(diǎn)的大小。大于0的整數(shù),必需是整數(shù)。實(shí)際輸入<=0的數(shù)字也可,但是估計(jì)程序里有判斷,<=0等同于1。默認(rèn)值是20。
- thickness:點(diǎn)的線寬。必需是大于0的整數(shù),必需是整數(shù),不能小于0,默認(rèn)值是1。
- line_type:線的類型??梢匀〉闹涤衏v2.LINE_4,cv2.LINE_8,cv2.LINE_AA。其中cv2.LINE_AA的AA表示抗鋸齒,線會(huì)更平滑。
markerType取值說(shuō)明
| 數(shù)值 | 宏定義 | 說(shuō)明 |
|---|---|---|
| 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示例
下面是一個(gè)簡(jiǎn)單的畫(huà)點(diǎn)程序
# -*- 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()
請(qǐng)?zhí)貏e注意,opencv在調(diào)用這些畫(huà)圖函數(shù)后,image的內(nèi)容會(huì)被這些畫(huà)圖函數(shù)改變,也就是說(shuō),函數(shù)調(diào)用之后,我們就拿不回原始的image了,除非另外保存一份原始image的副本。在寫(xiě)一些交互畫(huà)圖函數(shù)時(shí),這個(gè)特性需要格外注意。
程序執(zhí)行結(jié)果如下。

利用鼠標(biāo)回調(diào)函數(shù)交互式畫(huà)點(diǎn)
例1,簡(jiǎn)單的例子
# -*- 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()
上面程序中有幾個(gè)注意點(diǎn):
- setMouseCallback()中的param參數(shù)我們傳遞了image進(jìn)去,也就是說(shuō)鼠標(biāo)回調(diào)函數(shù)onmouse_pick_points()中的param就是image,畫(huà)點(diǎn)的操作在鼠標(biāo)回調(diào)函數(shù)中,該參數(shù)在onmouse_pick_points中的變化可以保留到函數(shù)外,可以理解為C++的引用傳遞,或C語(yǔ)言的指針傳遞。
- 需要一個(gè)無(wú)限循環(huán)來(lái)刷新圖像。
- 無(wú)限循環(huán)的退出條件由鍵盤(pán)獲取,cv2.waitKey()用來(lái)獲取鍵盤(pán)的按鍵,當(dāng)我們點(diǎn)ESC后就可以退出。
這里點(diǎn)了三次左鍵,終端輸出以下內(nèi)容:
x = 60, y = 55 x = 206, y = 113 x = 114, y = 192
并得到這樣一張圖像:

例2,刪除功能
如果需要?jiǎng)h除已經(jīng)畫(huà)了的點(diǎn)的功能,那么問(wèn)題就變得略有些復(fù)雜了。
我們之前講過(guò),opencv在畫(huà)了這些點(diǎn)之后,圖像的像素已經(jīng)事實(shí)上被改變了,想要緊緊通過(guò)當(dāng)前圖像將其恢復(fù)原狀是不行的。所以為了實(shí)現(xiàn)刪除功能,我們需要備份一張?jiān)紙D像,一張用來(lái)對(duì)外顯示的圖像,以及一個(gè)由點(diǎn)坐標(biāo)組成的list。
每次做刪除點(diǎn)的操作后,我們都使用原始圖像重置對(duì)外顯示的圖像,然后再把list中所有的點(diǎn)都重新畫(huà)在對(duì)外顯示的圖像上,就可以實(shí)現(xiàn)刪除點(diǎn)的效果。如果是增加點(diǎn)的操作,則不用重置圖像。
實(shí)現(xiàn)代碼如下:
下面代碼中,左鍵實(shí)現(xiàn)增加一個(gè)點(diǎn)的操作,右鍵依次刪除后面畫(huà)上的點(diǎ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鼠標(biāo)畫(huà)點(diǎn)之cv2.drawMarker()函數(shù)的文章就介紹到這了,更多相關(guān)opencv鼠標(biāo)畫(huà)點(diǎn)cv2.drawMarker()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python利用字典和列表實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Python如何利用字典和列表實(shí)現(xiàn)一個(gè)簡(jiǎn)易的學(xué)生信息管理系統(tǒng),文中詳細(xì)注釋,方便理解,需要的可以參考一下2022-06-06
基于Python創(chuàng)建語(yǔ)音識(shí)別控制系統(tǒng)
這篇文章主要介紹了通過(guò)Python實(shí)現(xiàn)創(chuàng)建語(yǔ)音識(shí)別控制系統(tǒng),能利用語(yǔ)音識(shí)別識(shí)別說(shuō)出來(lái)的文字,根據(jù)文字的內(nèi)容來(lái)控制圖形移動(dòng),感興趣的同學(xué)可以關(guān)注一下2021-12-12
Python技能樹(shù)共建之python?urllib?模塊
這篇文章介紹了Python技能樹(shù)共建之python?urllib?模塊,urllib模塊是?Python?標(biāo)準(zhǔn)庫(kù),更多相關(guān)介紹需要的小伙伴可以參考下面文章的詳細(xì)內(nèi)容2022-05-05
Python?數(shù)據(jù)篩選功能實(shí)現(xiàn)
這篇文章主要介紹了Python?數(shù)據(jù)篩選,無(wú)論是在數(shù)據(jù)分析還是數(shù)據(jù)挖掘的時(shí)候,數(shù)據(jù)篩選總會(huì)涉及到,這里我總結(jié)了一下python中列表,字典,數(shù)據(jù)框中一些常用的數(shù)據(jù)篩選的方法,需要的朋友可以參考下2023-04-04
django商品分類及商品數(shù)據(jù)建模實(shí)例詳解
這篇文章主要介紹了django商品分類及商品數(shù)據(jù)建模實(shí)例代碼內(nèi)容,需要的朋友們學(xué)習(xí)參考下。2020-01-01
python數(shù)據(jù)預(yù)處理之將類別數(shù)據(jù)轉(zhuǎn)換為數(shù)值的方法
下面小編就為大家?guī)?lái)一篇python數(shù)據(jù)預(yù)處理之將類別數(shù)據(jù)轉(zhuǎn)換為數(shù)值的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
Python實(shí)現(xiàn)繪制雙柱狀圖并顯示數(shù)值功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)繪制雙柱狀圖并顯示數(shù)值功能,涉及Python數(shù)值運(yùn)算及基于matplotlib的圖形繪制相關(guān)操作技巧,需要的朋友可以參考下2018-06-06
Python圖像的增強(qiáng)處理操作示例【基于ImageEnhance類】
這篇文章主要介紹了Python圖像的增強(qiáng)處理操作,結(jié)合實(shí)例形式分析了使用ImageEnhance類處理圖片的亮度、對(duì)比度、色度以及銳度等相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
Python??序列化反序列化和異常處理的問(wèn)題小結(jié)
這篇文章主要介紹了Python?序列化反序列化和異常處理,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12

