欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python opencv鼠標(biāo)畫矩形框之cv2.rectangle()函數(shù)

 更新時(shí)間:2021年10月11日 09:40:17   作者:拜陽  
鼠標(biāo)操作屬于用戶接口設(shè)計(jì),以前一直使用Qt來做,但是如果只需要簡單的鼠標(biāo),鍵盤操作,直接調(diào)用opencv庫的函數(shù)也未嘗不可,下面這篇文章主要給大家介紹了關(guān)于python opencv鼠標(biāo)畫矩形框cv2.rectangle()函數(shù)的相關(guān)資料,需要的朋友可以參考下

關(guān)于鼠標(biāo)回調(diào)函數(shù)的說明可以參考:opencv-python的鼠標(biāo)交互操作

cv2.rectangle()函數(shù)說明

參數(shù)說明

導(dǎo)入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

其中四個(gè)參數(shù)必選:

  • img:底圖,uint8類型的ndarray
  • pt1:矩形框的一個(gè)頂點(diǎn)坐標(biāo),是一個(gè)包含兩個(gè)數(shù)字的tuple(必需是tuple),表示(x, y)
  • pt2:pt1的對角線頂點(diǎn)坐標(biāo),類型同pt1
  • color:顏色,是一個(gè)包含三個(gè)數(shù)字的tuple或list,表示(b, g, r);如果圖片是灰度圖的話,color也可以是一個(gè)數(shù)字

其他參數(shù)說明如下:

  • thickness:線寬,默認(rèn)值是1,數(shù)值越大表示線寬越寬;如果取值為負(fù)數(shù)或者cv2.FILLED,那么將畫一個(gè)填充了的矩形
  • lineType:可以取的值有cv2.LINE_4,cv2.LINE_8,cv2.LINE_AA。其中cv2.LINE_AA的AA表示抗鋸齒,線會(huì)更平滑。

注意:pt1和pt2表示任意一對對角線上的點(diǎn),不一定要求pt1必需左上角,pt2必需右下角。另外pt1和pt2可以互換順序而不影響結(jié)果。

下面是一個(gè)非交互式的程序示例

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

第一個(gè)矩形框pt1 = 左上角,pt2 = 右下角

第二個(gè)矩形框pt1 = 右下角,pt2 = 左上角

第三個(gè)矩形框pt1 = 右上角,pt2 = 左下角

得到的結(jié)果如下:

利用鼠標(biāo)回調(diào)函數(shù)交互式畫矩形框

為了容易理解下面程序,建議先參考下面文章的例2

opencv-python鼠標(biāo)畫點(diǎn):cv2.drawMarker()

下面程序的操作方法是:

  • 鼠標(biāo)左鍵按下開始畫當(dāng)前矩形框
  • 移動(dòng)鼠標(biāo)進(jìn)行繪畫
  • 彈起左鍵當(dāng)前矩形框繪畫結(jié)束,并把當(dāng)前矩形框加入列表
  • 鼠標(biāo)右鍵按下是刪除矩形框列表中的最后一個(gè)對象

編程注意事項(xiàng):

  • 矩形框繪畫過程中需要記錄一個(gè)鼠標(biāo)左鍵按下的狀態(tài)標(biāo)志。常規(guī)狀態(tài)下該標(biāo)志設(shè)為False,鼠標(biāo)移動(dòng)不進(jìn)行繪畫;當(dāng)鼠標(biāo)左鍵按下后,標(biāo)志設(shè)為True,此時(shí)移動(dòng)鼠標(biāo)將進(jìn)入繪畫狀態(tài);左鍵彈起后,標(biāo)志恢復(fù)False。
  • 為了在鼠標(biāo)移動(dòng)過程中實(shí)時(shí)顯示繪畫狀態(tài),需要不停地重置用來顯示的圖像,并不停地重畫所有已保存的矩形框
  • 矩形框的第二個(gè)點(diǎn)使用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鼠標(biāo)畫矩形框之cv2.rectangle()函數(shù)的文章就介紹到這了,更多相關(guān)opencv鼠標(biāo)畫矩形框cv2.rectangle()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python Tkinter 簡單登錄界面的實(shí)現(xiàn)

    Python Tkinter 簡單登錄界面的實(shí)現(xiàn)

    今天小編就為大家分享一篇Python Tkinter 簡單登錄界面的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • 詳解基于K-means的用戶畫像聚類模型

    詳解基于K-means的用戶畫像聚類模型

    這篇文章主要介紹了基于K-means的用戶畫像聚類模型,本文中就是使用one-hot思想將不同維度的數(shù)據(jù)利用字典映射的方式將其轉(zhuǎn)化為數(shù)據(jù)向量,需要的朋友可以參考下
    2022-05-05
  • Python實(shí)現(xiàn)蟻群算法

    Python實(shí)現(xiàn)蟻群算法

    本文主要介紹了Python實(shí)現(xiàn)蟻群算法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 如何設(shè)置PyCharm中的Python代碼模版(推薦)

    如何設(shè)置PyCharm中的Python代碼模版(推薦)

    這篇文章主要介紹了如何設(shè)置PyCharm中的Python代碼模版,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Python 使用Opencv實(shí)現(xiàn)目標(biāo)檢測與識(shí)別的示例代碼

    Python 使用Opencv實(shí)現(xiàn)目標(biāo)檢測與識(shí)別的示例代碼

    這篇文章主要介紹了Python 使用Opencv實(shí)現(xiàn)目標(biāo)檢測與識(shí)別的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • win系統(tǒng)下為Python3.5安裝flask-mongoengine 庫

    win系統(tǒng)下為Python3.5安裝flask-mongoengine 庫

    MongoEngine 是一個(gè)用來操作 MongoDB 的 ORM 框架,如果你不知道什么是 ORM,可以參考 Flask-SQLAlchemy 一節(jié)。在 Flask 中,我們可以直接使用 MongoEngine,也可使用 Flask-MongoEngine ,它使得在 Flask 中使用 MongoEngine 變得更加簡單。
    2016-12-12
  • pytorch DataLoader的num_workers參數(shù)與設(shè)置大小詳解

    pytorch DataLoader的num_workers參數(shù)與設(shè)置大小詳解

    這篇文章主要介紹了pytorch DataLoader的num_workers參數(shù)與設(shè)置大小詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 詳解python os.walk()方法的使用

    詳解python os.walk()方法的使用

    今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識(shí),文章圍繞python os.walk()方法的使用展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • python實(shí)現(xiàn)文件路徑和url相互轉(zhuǎn)換的方法

    python實(shí)現(xiàn)文件路徑和url相互轉(zhuǎn)換的方法

    這篇文章主要介紹了python實(shí)現(xiàn)文件路徑和url相互轉(zhuǎn)換的方法,以URL轉(zhuǎn)換成文件路徑為例分析了Python實(shí)現(xiàn)地址轉(zhuǎn)換的技巧,需要的朋友可以參考下
    2015-07-07
  • 用Python登錄Gmail并發(fā)送Gmail郵件的教程

    用Python登錄Gmail并發(fā)送Gmail郵件的教程

    這篇文章主要介紹了用Python登錄Gmail并發(fā)送Gmail郵件的教程,利用了Python的SMTP庫,代碼非常簡單,需要的朋友可以參考下
    2015-04-04

最新評論