zl程序教程

您现在的位置是:首页 >  后端

当前栏目

opencv十字瞄准线 在图像上长按左键画矩形单击右键清除

Opencv 图像 清除 矩形 瞄准
2023-09-27 14:25:50 时间

版本一

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, center=(10,10), radius=100):
        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


        self.center = center
        self.radius = radius

        self.clearImg = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
        self.image_for_show_line = image.copy()


    @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 save_images_rect(self):
        cv2.imwrite("Rect.jpg", draw_rects.image_for_show)



    def draw_crossline(self):
        pt_left = (self.center[0] - self.radius, self.center[1])
        pt_right = (self.center[0] + self.radius, self.center[1])
        pt_top = (self.center[0], self.center[1] - self.radius)
        pt_bottom = (self.center[0], self.center[1] + self.radius)
        cv2.line(self.image_for_show, pt_left, pt_right,
                 (0, 0, 255), 1)
        cv2.line(self.image_for_show, pt_top, pt_bottom,
                 (0, 0, 255), 1)


def onmouse_draw_rect(event, x, y, flags, draw_rects):
    draw_rects.center = (x, y)

    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()
        draw_rects.save_images_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()
        draw_rects.save_images_rect()
        # print("clear")







if __name__ == '__main__':
    image = cv2.imread("result.png")
    draw_rects = DrawRects(image, (0, 255, 0), 2, (10, 10), 10000)
    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()

在版本一的基础上加十字瞄准线

通过两图叠加,不太满意,会影响原图的本来显示情况

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, center=(10,10), radius=100):
        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


        self.center = center
        self.radius = radius

        self.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)


    @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 save_images_rect(self):
        cv2.imwrite("Rect.jpg", draw_rects.image_for_show)


    def trans_img(self):
        self.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)



    def draw_crossline(self):
        self.trans_img()
        pt_left = (self.center[0] - self.radius, self.center[1])
        pt_right = (self.center[0] + self.radius, self.center[1])
        pt_top = (self.center[0], self.center[1] - self.radius)
        pt_bottom = (self.center[0], self.center[1] + self.radius)
        cv2.line(self.image_for_show_line, pt_left, pt_right,
                 (0, 0, 255), 3)
        cv2.line(self.image_for_show_line, pt_top, pt_bottom,
                 (0, 0, 255), 3)

        # cv2.imshow("crossLine", self.image_for_show_line)
        # print("crossline")


def onmouse_draw_rect(event, x, y, flags, draw_rects):
    draw_rects.center = (x, y)

    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()
        draw_rects.save_images_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()
        draw_rects.save_images_rect()
        # print("clear")

    draw_rects.draw_crossline()





if __name__ == '__main__':
    image = cv2.imread("result.png")
    draw_rects = DrawRects(image, (0, 255, 0), 2, (10, 10), 10000)
    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)
        # cv2.imshow(WIN_NAME, two_images_merge(draw_rects.image_for_show,draw_rects.image_for_show_line))
        # cv2.imshow("img1", draw_rects.image_for_show)
        # cv2.imshow("img2", draw_rects.image_for_show_line)
        # cv2.waitKey()
        dest = cv2.addWeighted(draw_rects.image_for_show_line,0.1, draw_rects.image_for_show,0.9, 20)
        cv2.imshow(WIN_NAME, dest)
        key = cv2.waitKey(30)
        if key == 27:  # ESC
            break
    cv2.destroyAllWindows()

版本三,完善实现功能

将 

dest = cv2.addWeighted(draw_rects.image_for_show_line,0.1, draw_rects.image_for_show,0.9, 20)
修改为
dest = cv2.add(draw_rects.image_for_show_line, draw_rects.image_for_show)
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, center=(10,10), radius=100):
        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


        self.center = center
        self.radius = radius

        self.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)


    @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 save_images_rect(self):
        cv2.imwrite("Rect.jpg", draw_rects.image_for_show)


    def trans_img(self):
        self.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)



    def draw_crossline(self):
        self.trans_img()
        pt_left = (self.center[0] - self.radius, self.center[1])
        pt_right = (self.center[0] + self.radius, self.center[1])
        pt_top = (self.center[0], self.center[1] - self.radius)
        pt_bottom = (self.center[0], self.center[1] + self.radius)
        cv2.line(self.image_for_show_line, pt_left, pt_right,
                 (0, 0, 255), 1)
        cv2.line(self.image_for_show_line, pt_top, pt_bottom,
                 (0, 0, 255), 1)

        # cv2.imshow("crossLine", self.image_for_show_line)
        # print("crossline")


def onmouse_draw_rect(event, x, y, flags, draw_rects):
    draw_rects.center = (x, y)

    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()
        draw_rects.save_images_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()
        draw_rects.save_images_rect()
        # print("clear")

    draw_rects.draw_crossline()





if __name__ == '__main__':
    image = cv2.imread("result.png")
    draw_rects = DrawRects(image, (0, 255, 0), 2, (10, 10), 10000)
    cv2.namedWindow(WIN_NAME, 0)
    cv2.setMouseCallback(WIN_NAME, onmouse_draw_rect, draw_rects)

    while True:
        dest = cv2.add(draw_rects.image_for_show_line, draw_rects.image_for_show)

        cv2.imshow(WIN_NAME, dest)
        key = cv2.waitKey(30)
        if key == 27:  # ESC
            break
    cv2.destroyAllWindows()

版本4 保存画框的ROI

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, center=(10, 10), radius=100):
        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

        self.center = center
        self.radius = radius

        self.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)




    @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 getROI(self):
        roi = image[self.current_rect.tl[1]:self.current_rect.br[1], self.current_rect.tl[0]:self.current_rect.br[0]]
        cv2.imwrite("ROI.jpg",roi)

    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 save_images_rect(self):
        cv2.imwrite("Rect.jpg", draw_rects.image_for_show)

    def trans_img(self):
        self.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)

    def draw_crossline(self):
        self.trans_img()
        pt_left = (self.center[0] - self.radius, self.center[1])
        pt_right = (self.center[0] + self.radius, self.center[1])
        pt_top = (self.center[0], self.center[1] - self.radius)
        pt_bottom = (self.center[0], self.center[1] + self.radius)
        cv2.line(self.image_for_show_line, pt_left, pt_right,
                 (0, 0, 255), 1)
        cv2.line(self.image_for_show_line, pt_top, pt_bottom,
                 (0, 0, 255), 1)

        # cv2.imshow("crossLine", self.image_for_show_line)
        # print("crossline")


def onmouse_draw_rect(event, x, y, flags, draw_rects):
    draw_rects.center = (x, y)

    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()
        draw_rects.save_images_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()
        draw_rects.getROI()

    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()
        draw_rects.save_images_rect()
        # print("clear")

    draw_rects.draw_crossline()


if __name__ == '__main__':
    image = cv2.imread("result.jpg")
    draw_rects = DrawRects(image, (0, 255, 0), 2, (10, 10), 10000)
    cv2.namedWindow(WIN_NAME, 0)
    cv2.setMouseCallback(WIN_NAME, onmouse_draw_rect, draw_rects)

    while True:
        dest = cv2.add(draw_rects.image_for_show_line, draw_rects.image_for_show)

        cv2.imshow(WIN_NAME, dest)
        key = cv2.waitKey(30)
        if key == 27:  # ESC
            break
    cv2.destroyAllWindows()