python opencv鼠标画点之cv2.drawMarker()函数

目录
  • 前言
  • cv2.drawMarker()函数说明
    • 参数说明
  • 利用鼠标回调函数交互式画点
    • 例1,简单的例子
    • 例2,删除功能
  • 总结

前言

这里所谓画点的意思是指在单一像素点上画一个标记符,而不是画小圆点。使用的函数是cv2.drawMarker(img, position, color, ...)

关于鼠标回调函数的说明可以参考:opencv-python的鼠标交互操作

cv2.drawMarker()函数说明

参数说明

导入cv2后,通过help(cv2.drawMarker)可以看到函数的帮助文档如下:

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]

其中三个必选参数:img, position, color,其他参数是可选。三个必选参数说明如下:

  • img:底图,uint8类型的ndarray,
  • position:坐标,是一个包含两个数字的tuple(必需是tuple),表示(x, y)
  • color:颜色,是一个包含三个数字的tuple或list,表示(b, g, r)

其他参数说明如下:

  • markerType:点的类型。取值0-6,有相应的宏定义与之对应,具体的可参考下面的一个表。
  • markerSize:点的大小。大于0的整数,必需是整数。实际输入<=0的数字也可,但是估计程序里有判断,<=0等同于1。默认值是20。
  • thickness:点的线宽。必需是大于0的整数,必需是整数,不能小于0,默认值是1。
  • line_type:线的类型。可以取的值有cv2.LINE_4,cv2.LINE_8,cv2.LINE_AA。其中cv2.LINE_AA的AA表示抗锯齿,线会更平滑。

markerType取值说明

数值 宏定义 说明
0 cv2.MARKER_CROSS 十字线(横竖两根线)
1 cv2.MARKER_TILTED_CROSS 交叉线(斜着两根线)
2 cv2.MARKER_STAR 米字线(横竖加斜着共四根线)
3 cv2.MARKER_DIAMOND 旋转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()

请特别注意,opencv在调用这些画图函数后,image的内容会被这些画图函数改变,也就是说,函数调用之后,我们就拿不回原始的image了,除非另外保存一份原始image的副本。在写一些交互画图函数时,这个特性需要格外注意。

程序执行结果如下。

利用鼠标回调函数交互式画点

例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参数我们传递了image进去,也就是说鼠标回调函数onmouse_pick_points()中的param就是image,画点的操作在鼠标回调函数中,该参数在onmouse_pick_points中的变化可以保留到函数外,可以理解为C++的引用传递,或C语言的指针传递。
  • 需要一个无限循环来刷新图像。
  • 无限循环的退出条件由键盘获取,cv2.waitKey()用来获取键盘的按键,当我们点ESC后就可以退出。

这里点了三次左键,终端输出以下内容:

x = 60, y = 55
x = 206, y = 113
x = 114, y = 192

并得到这样一张图像:

例2,删除功能

如果需要删除已经画了的点的功能,那么问题就变得略有些复杂了。

我们之前讲过,opencv在画了这些点之后,图像的像素已经事实上被改变了,想要紧紧通过当前图像将其恢复原状是不行的。所以为了实现删除功能,我们需要备份一张原始图像,一张用来对外显示的图像,以及一个由点坐标组成的list。

每次做删除点的操作后,我们都使用原始图像重置对外显示的图像,然后再把list中所有的点都重新画在对外显示的图像上,就可以实现删除点的效果。如果是增加点的操作,则不用重置图像。

实现代码如下:

下面代码中,左键实现增加一个点的操作,右键依次删除后面画上的点。

# -*- 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

得到的结果如下:

总结

到此这篇关于python opencv鼠标画点之cv2.drawMarker()函数的文章就介绍到这了,更多相关opencv鼠标画点cv2.drawMarker()内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python opencv鼠标事件实现画框圈定目标获取坐标信息

    本文实例为大家分享了python-opencv鼠标事件画框圈定目标的具体代码,供大家参考,具体内容如下 在视频/相机中,用鼠标画矩形框,圈定目标,从而获得鼠标的起始坐标点a.终止坐标点b # -*- coding: utf-8 -*- """ Created on Tue Dec 27 09:32:02 2016 @author: http://blog.csdn.net/lql0716 """ import cv2 import numpy a

  • opencv3/python 鼠标响应操作详解

    鼠标回调函数: def setMouseCallback( windowName, #窗口名称 onMouse, #鼠标响应处理函数 param=None) #处理函数的ID event鼠标事件: event: EVENT_LBUTTONDBLCLK = 7 左键双击 EVENT_LBUTTONDOWN = 1 左键点击 EVENT_LBUTTONUP = 4 左键释放 EVENT_MBUTTONDBLCLK = 9 中间释放 EVENT_MBUTTONDOWN = 3 中间点击 EVENT_M

  • OpenCV实现鼠标框选并显示框选区域

    本文实例为大家分享了OpenCV实现鼠标框选并显示框选区域的具体代码,供大家参考,具体内容如下 cvSetImageROI函数(基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)) void cvSetImageROI(IplImage* image,CvRect rect) 参数: image 图像头,待处理图像 rect ROI 感兴趣区域矩形 cvResetImageROI函数(释放基于给定的矩形设置图像的ROI(感兴趣区域,region of int

  • Opencv使用鼠标任意形状的抠图

    本文实例为大家分享了Opencv使用鼠标任意形状抠图的具体代码,供大家参考,具体内容如下 主要的方法思路是:首先利用鼠标在图上画任意形状,利用掩码将任意形状抠出来 主要难点是怎么填充,因为鼠标在画线的时候,滑动越快,点是不连续的,利用floodFill和drawContours都是没有办法进行填充的,从另一个方面想,一个面是由很多个点组成的,虽然鼠标滑动保存下来的就是一系列点,可以利用这一系列点构成一个面,利用面的性质进行填充就比较简单了. 一.首先使用鼠标点击事件,鼠标点击事件的函数为: vo

  • Python OpenCV实现鼠标画框效果

    使用Python+OpenCV实现鼠标画框的代码,供大家参考,具体内容如下 # -*-coding: utf-8 -*- """ @Project: IntelligentManufacture @File : user_interaction.py @Author : panjq @E-mail : pan_jinquan@163.com @Date : 2019-02-21 15:03:18 """ # -*- coding: utf-8 -

  • python opencv鼠标画点之cv2.drawMarker()函数

    目录 前言 cv2.drawMarker()函数说明 参数说明 利用鼠标回调函数交互式画点 例1,简单的例子 例2,删除功能 总结 前言 这里所谓画点的意思是指在单一像素点上画一个标记符,而不是画小圆点.使用的函数是cv2.drawMarker(img, position, color, ...) 关于鼠标回调函数的说明可以参考:opencv-python的鼠标交互操作 cv2.drawMarker()函数说明 参数说明 导入cv2后,通过help(cv2.drawMarker)可以看到函数的帮

  • python opencv鼠标画矩形框之cv2.rectangle()函数

    目录 cv2.rectangle()函数说明 参数说明 利用鼠标回调函数交互式画矩形框 总结 关于鼠标回调函数的说明可以参考:opencv-python的鼠标交互操作 cv2.rectangle()函数说明 参数说明 导入cv2后,通过help(cv2.rectangle)可以看到函数的帮助文档如下: rectangle(...) rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img . @brief D

  • python opencv鼠标交互操作的实用指南

    目录 前言 cv2.setMouseCallback(windowName, onMouse [, param]) 鼠标回调函数:onMouse(event, x, y, flags, param) 示例 总结 前言 opencv的鼠标交互操作主要通过两个函数实现: 第一个是cv2.setMouseCallback(windowName, onMouse [, param]) 第二个是setMouseCallback()的第二个参数,称为鼠标回调函数onMouse(event, x, y, fl

  • Python OpenCV 基于图像边缘提取的轮廓发现函数

    基础知识铺垫 在图像中,轮廓可以简单的理解为连接具有相同颜色的所有连续点(边界)的曲线,轮廓可用于形状分析和对象检测.识别等领域. 轮廓发现的原理:先通过阈值分割提取目标物体,再通过边缘检测提取目标物体轮廓. 一个轮廓就是一系列的点(像素),这些点构成了一个有序的点集合. 使用 cv2.findContours 函数可以用来检测图像的边缘. 函数原型说明 contours, hierarchy = cv2.findContours(image, mode, method[, contours[,

  • python opencv实现图像边缘检测

    本文利用python opencv进行图像的边缘检测,一般要经过如下几个步骤: 1.去噪 如cv2.GaussianBlur()等函数: 2.计算图像梯度 图像梯度表达的是各个像素点之间,像素值大小的变化幅度大小,变化较大,则可以认为是出于边缘位置,最多可简化为如下形式: 3.非极大值抑制 在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点.对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的.如下图所示: 4.滞后阈值 现在要确定那些边界才是真正的

  • Python OpenCV获取视频的方法

    之前有文章,使用Android平台的OpenCV接入了视频,控制的目标是手机的摄像头,这是OpenCV的好处,使用OpenCV可以使用跨平台的接口实现相同的功能,减少了平台间移植的困难.正如本文后面,将使用类似的接口,从笔记本的摄像头获取视频,所以,尝试本文代码需要有一台有摄像头的电脑. 不过,需要说明的的是,OpenCV的强项在于图像相关的处理,而不是视频的编解码,所以,不要使用OpenCV做多余的事情,我们使用OpenCV接入视频或者图片的目的,是为了对视频或图片进行处理. 关于Python

  • Python+OpenCV实现鼠标画瞄准星的方法详解

    目录 函数说明 cv2.circle() cv2.line() 简单的例子 利用鼠标回调函数画瞄准星 所谓瞄准星指的是一个圆圈加一个圆圈内的十字线,就像玩射击游戏狙击枪开镜的样子一样.这里并不是直接在图上画一个瞄准星,而是让这个瞄准星跟着鼠标走.在图像标注任务中,可以利用瞄准星进行一些辅助,特别是回归类的任务,使用该功能可以使得关键点的标注更加精准. 关于鼠标回调函数的说明可以参考:opencv-python的鼠标交互操作 函数说明 import cv2后,可以分别help(cv2.circle

  • python opencv画局部放大图实例教程

    目录 为什么要画局部放大图? 程序逻辑 程序实例 总结 这项功能的目的是为了方便使用opencv做图像标注工具. 为什么要画局部放大图? 在做图像数据标注时,很难一次就做到精准标注,经常需要微调才能达到比较好的标注效果.如果目标比较小,即使微调也难以做到精准,所以就需要另外一个窗口对标注区域进行局部放大以方便微调. 程序逻辑 本文中标注信息以矩形框作为示例,矩形框是图像标注中最常用到的一种标注信息形态.其他标注信息的设计逻辑雷同. 程序主要逻辑是:鼠标在任意窗口中做的操作都要同步映射到另外一个窗

随机推荐