ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python使用opencv鼠标动态画矩形框

2022-04-13 02:31:18  阅读:385  来源: 互联网

标签:draw python self cv2 矩形框 opencv rects image rect


cv2.rectangle()函数说明

其中四个参数必选:

  • img:底图,uint8类型的ndarray
  • pt1:矩形框的一个顶点坐标,是一个包含两个数字的tuple(必需是tuple),表示(x, y)
  • pt2:pt1的对角线顶点坐标,类型同pt1
  • color:颜色,是一个包含三个数字的tuple或list,表示(b, g, r);如果图片是灰度图的话,color也可以是一个数字

其他参数说明如下:

  • thickness:线宽,默认值是1,数值越大表示线宽越宽;如果取值为负数或者cv2.FILLED,那么将画一个填充了的矩形
  • lineType:可以取的值有cv2.LINE_4,cv2.LINE_8,cv2.LINE_AA。其中cv2.LINE_AA的AA表示抗锯齿,线会更平滑。

下面是一个非交互式的程序示例

# -*- 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.rectangle(image, (20, 20), (60, 60), (0, 255, 0))
    cv2.rectangle(image, (120, 120), (80, 80), (255, 0, 0), thickness=-1)
    cv2.rectangle(image, (140, 200), (200, 140), (0, 0, 255), thickness=5)
    cv2.namedWindow('rect', 1)
    cv2.imshow('rect', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

  

利用鼠标回调函数交互式画矩形框

 

 

# -*- coding: utf-8 -*-

import copy
import cv2
import numpy as np

WIN_NAME = 'draw_rect'


class Rect(object):
    def __init__(self):
        self.tl = (0, 0)
        self.br = (0, 0)

    def regularize(self):
        """
        make sure tl = TopLeft point, br = BottomRight point
        """
        pt1 = (min(self.tl[0], self.br[0]), min(self.tl[1], self.br[1]))
        pt2 = (max(self.tl[0], self.br[0]), max(self.tl[1], self.br[1]))
        self.tl = pt1
        self.br = pt2


class DrawRects(object):
    def __init__(self, image, color, thickness=1):
        self.original_image = image
        self.image_for_show = image.copy()
        self.color = color
        self.thickness = thickness
        self.rects = []
        self.current_rect = Rect()
        self.left_button_down = False

    @staticmethod
    def __clip(value, low, high):
        """
        clip value between low and high

        Parameters
        ----------
        value: a number
            value to be clipped
        low: a number
            low limit
        high: a number
            high limit

        Returns
        -------
        output: a number
            clipped value
        """
        output = max(value, low)
        output = min(output, high)
        return output

    def shrink_point(self, x, y):
        """
        shrink point (x, y) to inside image_for_show

        Parameters
        ----------
        x, y: int, int
            coordinate of a point

        Returns
        -------
        x_shrink, y_shrink: int, int
            shrinked coordinate
        """
        height, width = self.image_for_show.shape[0:2]
        x_shrink = self.__clip(x, 0, width)
        y_shrink = self.__clip(y, 0, height)
        return (x_shrink, y_shrink)

    def append(self):
        """
        add a rect to rects list
        """
        self.rects.append(copy.deepcopy(self.current_rect))

    def pop(self):
        """
        pop a rect from rects list
        """
        rect = Rect()
        if self.rects:
            rect = self.rects.pop()
        return rect

    def reset_image(self):
        """
        reset image_for_show using original image
        """
        self.image_for_show = self.original_image.copy()

    def draw(self):
        """
        draw rects on image_for_show
        """
        for rect in self.rects:
            cv2.rectangle(self.image_for_show, rect.tl, rect.br,
                          color=self.color, thickness=self.thickness)

    def draw_current_rect(self):
        """
        draw current rect on image_for_show
        """
        cv2.rectangle(self.image_for_show,
                      self.current_rect.tl, self.current_rect.br,
                      color=self.color, thickness=self.thickness)


def onm ouse_draw_rect(event, x, y, flags, draw_rects):
    if event == cv2.EVENT_LBUTTONDOWN:
        # pick first point of rect
        print('pt1: x = %d, y = %d' % (x, y))
        draw_rects.left_button_down = True
        draw_rects.current_rect.tl = (x, y)
    if draw_rects.left_button_down and event == cv2.EVENT_MOUSEMOVE:
        # pick second point of rect and draw current rect
        draw_rects.current_rect.br = draw_rects.shrink_point(x, y)
        draw_rects.reset_image()
        draw_rects.draw()
        draw_rects.draw_current_rect()
    if event == cv2.EVENT_LBUTTONUP:
        # finish drawing current rect and append it to rects list
        draw_rects.left_button_down = False
        draw_rects.current_rect.br = draw_rects.shrink_point(x, y)
        print('pt2: x = %d, y = %d' % (draw_rects.current_rect.br[0],
                                       draw_rects.current_rect.br[1]))
        draw_rects.current_rect.regularize()
        draw_rects.append()
    if (not draw_rects.left_button_down) and event == cv2.EVENT_RBUTTONDOWN:
        # pop the last rect in rects list
        draw_rects.pop()
        draw_rects.reset_image()
        draw_rects.draw()


if __name__ == '__main__':
    image = np.zeros((256, 256, 3), np.uint8)
    draw_rects = DrawRects(image, (0, 255, 0), 2)
    cv2.namedWindow(WIN_NAME, 0)
    cv2.setMouseCallback(WIN_NAME, onm ouse_draw_rect, draw_rects)
    while True:
        cv2.imshow(WIN_NAME, draw_rects.image_for_show)
        key = cv2.waitKey(30)
        if key == 27:  # ESC
            break
    cv2.destroyAllWindows()

  

 一个简单的但是有问题的例子

 

 

# -*- coding: utf-8 -*-

import cv2
import numpy as np
drawing = False #是否开启画图
drawmode = True # True 矩形  False 圆形
ix,iy = -1,-1


def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,drawmode
    if event==cv2.EVENT_FLAG_LBUTTON:#左键按下
        drawing = True
        ix, iy = x, y
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:#左键按下和移动
        if drawing==True:
            if drawmode==True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,250,0), 3,cv2.LINE_AA)
            else:
                cv2.circle(img,(x,y),3,(0,255,0),3)
        elif event == cv2.EVENT_FLAG_LBUTTON:
            drawing==False

img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('opencv')
cv2.setMouseCallback('opencv',draw_circle)
while(1):
    cv2.imshow('opencv',img)
    key=cv2.waitKey(1)
    if key & 0xFF == ord('q'):
        break
    elif key &0xFF == ord('m'):
        drawmode = not drawmode
cv2.imwrite('./1.jpg',img)
cv2.destroyAllWindows()

  

标签:draw,python,self,cv2,矩形框,opencv,rects,image,rect
来源: https://www.cnblogs.com/gooutlook/p/16138446.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有