python opencv鼠標畫矩形框之cv2.rectangle()函數(shù)
關(guān)于鼠標回調(diào)函數(shù)的說明可以參考:opencv-python的鼠標交互操作
cv2.rectangle()函數(shù)說明
參數(shù)說明
導入cv2后,通過help(cv2.rectangle)可以看到函數(shù)的幫助文檔如下:
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
其中四個參數(shù)必選:
- img:底圖,uint8類型的ndarray
- pt1:矩形框的一個頂點坐標,是一個包含兩個數(shù)字的tuple(必需是tuple),表示(x, y)
- pt2:pt1的對角線頂點坐標,類型同pt1
- color:顏色,是一個包含三個數(shù)字的tuple或list,表示(b, g, r);如果圖片是灰度圖的話,color也可以是一個數(shù)字
其他參數(shù)說明如下:
- thickness:線寬,默認值是1,數(shù)值越大表示線寬越寬;如果取值為負數(shù)或者cv2.FILLED,那么將畫一個填充了的矩形
- lineType:可以取的值有cv2.LINE_4,cv2.LINE_8,cv2.LINE_AA。其中cv2.LINE_AA的AA表示抗鋸齒,線會更平滑。
注意:pt1和pt2表示任意一對對角線上的點,不一定要求pt1必需左上角,pt2必需右下角。另外pt1和pt2可以互換順序而不影響結(jié)果。
下面是一個非交互式的程序示例
# -*- 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()
第一個矩形框pt1 = 左上角,pt2 = 右下角
第二個矩形框pt1 = 右下角,pt2 = 左上角
第三個矩形框pt1 = 右上角,pt2 = 左下角
得到的結(jié)果如下:

利用鼠標回調(diào)函數(shù)交互式畫矩形框
為了容易理解下面程序,建議先參考下面文章的例2
opencv-python鼠標畫點:cv2.drawMarker()
下面程序的操作方法是:
- 鼠標左鍵按下開始畫當前矩形框
- 移動鼠標進行繪畫
- 彈起左鍵當前矩形框繪畫結(jié)束,并把當前矩形框加入列表
- 鼠標右鍵按下是刪除矩形框列表中的最后一個對象
編程注意事項:
- 矩形框繪畫過程中需要記錄一個鼠標左鍵按下的狀態(tài)標志。常規(guī)狀態(tài)下該標志設為False,鼠標移動不進行繪畫;當鼠標左鍵按下后,標志設為True,此時移動鼠標將進入繪畫狀態(tài);左鍵彈起后,標志恢復False。
- 為了在鼠標移動過程中實時顯示繪畫狀態(tài),需要不停地重置用來顯示的圖像,并不停地重畫所有已保存的矩形框
- 矩形框的第二個點使用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):
"""
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_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, 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
結(jié)果如下:

總結(jié)
到此這篇關(guān)于python opencv鼠標畫矩形框之cv2.rectangle()函數(shù)的文章就介紹到這了,更多相關(guān)opencv鼠標畫矩形框cv2.rectangle()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Python腳本在Linux下實現(xiàn)部分Bash Shell的教程
這篇文章主要介紹了使用Python腳本在Linux下實現(xiàn)部分Bash Shell的教程,包括一些簡單的輸入輸出和郵件功能,需要的朋友可以參考下2015-04-04
python使用wxpy輕松實現(xiàn)微信防撤回的方法
今天小編就為大家分享一篇python使用wxpy輕松實現(xiàn)微信防撤回的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02
Pytorch框架構(gòu)建ResNet模型的實現(xiàn)示例
本文主要介紹了Pytorch框架構(gòu)建ResNet模型的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-06-06
python3.5 + PyQt5 +Eric6 實現(xiàn)的一個計算器代碼
這篇文章主要介紹了python3.5 + PyQt5 +Eric6 實現(xiàn)的一個計算器代碼,在windows7 32位系統(tǒng)可以完美運行 計算器,有興趣的可以了解一下。2017-03-03
vue.js實現(xiàn)輸入框輸入值內(nèi)容實時響應變化示例
這篇文章主要介紹了vue.js實現(xiàn)輸入框輸入值內(nèi)容實時響應變化,結(jié)合實例形式分析了vue.js使用v-model屬性進行數(shù)據(jù)綁定的相關(guān)操作技巧,需要的朋友可以參考下2018-07-07

