开发者

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

开发者 https://www.devze.com 2022-12-02 12:11 出处:网络 作者: 拜阳
目录cv2.rectangle()函数说明参数说明利用鼠标回调函数交互式画矩形框总结关于鼠标回调函数的说明可以参考:opencv-python的鼠标交互操作
目录
  • cv2.rectangle()函数说明
    • 参数说明
  • 利用鼠标回调函数交互式画矩形框
    • 总结

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

      cv2.rectangle()函数说明编程客栈

      参数说明

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

      rectangle(...)
          rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
          .   @brief Draws a simple, thick, or filled up-right rectangle.
          .   
          .   The function cv::rectangle draws a rectangle outline or a filled rectangle whose two opposite corners
          .   are pt1 and pt2.
          .   
          .   @param img Image.
          .   @param pt1 Vertex of the rectangle.
          .   @param pt2 Vertex of the rectangle opposite to pt1 .
          .   @param color Rectangle color or brightness (grayscale image).
          .   @param thickness Thickness of lines that make up the rectangle. Negative values, like #FILLED,
          .   mean that the function has to draw a filled rectangle.
          .   @param lineType Type of the line. See #LineTypes
          .   @param shift Number of fractional bits in the point coordinates.
          
          
          
          rectangle(img, rec, color[, thickness[, lineType[, shift]]]) -> img
          .   @overload
          .   
          .   use `rec` parameter as alternative specification of the drawn rectangle: `r.tl() and
          .   r.br()-Point(1,1)` are opposite corners
      

      其中四个参数必选:

      • 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表示抗锯齿,线会更平滑。

      注意:pt1和pt2表示任意一对对角线上的点,不一定要求pt1必需左上角,pt2必需右下角。另外pt1和pt2可以互换顺序而不影响结果。

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

      # -*- 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', www.cppcns.comimage)
          cv2.waitKey(0)
          cv2.destroyAllWindows()
      

      第一个矩形框pt1 = 左上角,pt2 = 右下角

      第二个矩形框pt1 = 右下角,pt2 = 左上角

      第三个矩形框pt1 = 右上角,pt2 = 左下角

      得到的结果如下:

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

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

      为了容易理解下面程序,建议先参考下面文章的例2

      opencv-python鼠标画点:cv2.drawMarker()

      下面程序的操作方法是:

      • 鼠标左键按下开始画当前矩形框
      • 移动鼠标进行绘画
      • 弹起左键当前矩形框绘画结束,并把当前矩形框加入列表
      • 鼠标右键按下是删除矩形框列表中的最后一个对象

      编程注意事项:

      • 矩形框绘画过程中需要记录一个鼠标左键按下的状态标志。常规状态下该标志设为False,鼠标移动不进行绘画;当鼠标左键按下后,标志设为True,此时移动鼠标将进入绘画状态;左键弹起后,标志恢复False。
      • 为了在鼠标移动过程中实时显示绘画状态,需要不停地重置用来显示的图像,并不停地重画所有已保存的矩形框
      • 矩形框的第二个点使用shrink_point获取,确保不超出图像边界

      # -*- 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):http://www.cppcns.com
              """
          www.cppcns.com    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 onmouse_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_RBUT编程客栈TONDOWN:
              # 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, onmouse_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()
      

      终端输出:

      pt1: x = 55, y = 68

      pt2: x = 0, y = 0

      pt1: x = 195, y = 60

      pt2: x = 256, y = 0

      pt1: x = 59, y = 192

      pt2: x = 0, y = 256

      pt1: x = 194, y = 190

      pt2: x = 256, y = 256

      pt1: x = 94, y = 111

      pt2: x = 170, y = 168

      结果如下:

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

      总结

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

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消