版本一
import copyimport cv2import numpy as npWIN_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 = pt1self.br = pt2class DrawRects(object):def __init__(self, image, color, thickness=1, center=(10,10), radius=100):self.original_image = imageself.image_for_show = image.copy()self.color = colorself.thickness = thicknessself.rects = []self.current_rect = Rect()self.left_button_down = Falseself.center = centerself.radius = radiusself.clearImg = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)self.image_for_show_line = image.copy()@staticmethoddef __clip(value, low, high):"""clip value between low and highParameters----------value: a numbervalue to be clippedlow: a numberlow limithigh: a numberhigh limitReturns-------output: a numberclipped value"""output = max(value, low)output = min(output, high)return outputdef shrink_point(self, x, y):"""shrink point (x, y) to inside image_for_showParameters----------x, y: int, intcoordinate of a pointReturns-------x_shrink, y_shrink: int, intshrinked 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 rectdef 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 rectprint('pt1: x = %d, y = %d' % (x, y))draw_rects.left_button_down = Truedraw_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 rectdraw_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 listdraw_rects.left_button_down = Falsedraw_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 listdraw_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: # ESCbreakcv2.destroyAllWindows()
在版本一的基础上加十字瞄准线
通过两图叠加,不太满意,会影响原图的本来显示情况
import copyimport cv2import numpy as npWIN_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 = pt1self.br = pt2class DrawRects(object):def __init__(self, image, color, thickness=1, center=(10,10), radius=100):self.original_image = imageself.image_for_show = image.copy()self.color = colorself.thickness = thicknessself.rects = []self.current_rect = Rect()self.left_button_down = Falseself.center = centerself.radius = radiusself.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)@staticmethoddef __clip(value, low, high):"""clip value between low and highParameters----------value: a numbervalue to be clippedlow: a numberlow limithigh: a numberhigh limitReturns-------output: a numberclipped value"""output = max(value, low)output = min(output, high)return outputdef shrink_point(self, x, y):"""shrink point (x, y) to inside image_for_showParameters----------x, y: int, intcoordinate of a pointReturns-------x_shrink, y_shrink: int, intshrinked 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 rectdef 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 rectprint('pt1: x = %d, y = %d' % (x, y))draw_rects.left_button_down = Truedraw_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 rectdraw_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 listdraw_rects.left_button_down = Falsedraw_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 listdraw_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: # ESCbreakcv2.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 copyimport cv2import numpy as npWIN_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 = pt1self.br = pt2class DrawRects(object):def __init__(self, image, color, thickness=1, center=(10,10), radius=100):self.original_image = imageself.image_for_show = image.copy()self.color = colorself.thickness = thicknessself.rects = []self.current_rect = Rect()self.left_button_down = Falseself.center = centerself.radius = radiusself.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)@staticmethoddef __clip(value, low, high):"""clip value between low and highParameters----------value: a numbervalue to be clippedlow: a numberlow limithigh: a numberhigh limitReturns-------output: a numberclipped value"""output = max(value, low)output = min(output, high)return outputdef shrink_point(self, x, y):"""shrink point (x, y) to inside image_for_showParameters----------x, y: int, intcoordinate of a pointReturns-------x_shrink, y_shrink: int, intshrinked 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 rectdef 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 rectprint('pt1: x = %d, y = %d' % (x, y))draw_rects.left_button_down = Truedraw_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 rectdraw_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 listdraw_rects.left_button_down = Falsedraw_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 listdraw_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: # ESCbreakcv2.destroyAllWindows()
版本4 保存画框的ROI
import copyimport cv2import numpy as npWIN_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 = pt1self.br = pt2class DrawRects(object):def __init__(self, image, color, thickness=1, center=(10, 10), radius=100):self.original_image = imageself.image_for_show = image.copy()self.color = colorself.thickness = thicknessself.rects = []self.current_rect = Rect()self.left_button_down = Falseself.center = centerself.radius = radiusself.image_for_show_line = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)@staticmethoddef __clip(value, low, high):"""clip value between low and highParameters----------value: a numbervalue to be clippedlow: a numberlow limithigh: a numberhigh limitReturns-------output: a numberclipped value"""output = max(value, low)output = min(output, high)return outputdef 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_showParameters----------x, y: int, intcoordinate of a pointReturns-------x_shrink, y_shrink: int, intshrinked 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 rectdef 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 rectprint('pt1: x = %d, y = %d' % (x, y))draw_rects.left_button_down = Truedraw_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 rectdraw_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 listdraw_rects.left_button_down = Falsedraw_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 listdraw_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: # ESCbreakcv2.destroyAllWindows()