我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于OpenCV如何实现动态画矩形和多边形并保存坐标

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于OpenCV如何实现动态画矩形和多边形并保存坐标

这篇文章主要讲解了“基于OpenCV如何实现动态画矩形和多边形并保存坐标”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于OpenCV如何实现动态画矩形和多边形并保存坐标”吧!

1 画矩形和多边形,模式通过键盘控制

# 通过键盘s和p区别画矩形和多边形并保存坐标# 画矩形是OPencv自带的,只能通过按enter结束 import copyimport jsonimport joblibimport cv2import numpy as npimport osimport matplotlib.pyplot as pltimport imutilsfrom win32 import win32gui, win32printfrom win32.lib import win32conWIN_NAME = 'draw_rect'   def get_list0(path):    if not os.path.exists(path):        print("记录该型号标准位置的文件缺失/或输入型号与其对应标准文件名称不一致")    file1 = open(path, 'r')    lines = file1.readlines()    # for line in lines:    #     if (any(kw in line for kw in kws)):    #         SeriousFix.write(line + '\n')    zb0, list0 = [], []    for i in range(len(lines)):  # 取坐标        if lines[i] != '(pt1,pt2):\n':            zb0.append(lines[i][:-1])    # print(zb0)    for i in range(0, len(zb0)):  # 转换整数        zb0[i] = int(zb0[i])    # print(zb0)     for i in range(0, len(zb0), 4):  # 每四个取一次,加入列表        x0, y0, x1, y1 = zb0[i: i + 4]         # 使点设为左上至右下        if y1<=y0:            temp = y0            y0 = y1            y1 = temp         # print(x0,y0,x1,y1)        list0.append([x0, y0, x1, y1])    print("list0:", list0)    file1.close()    return list0  '''        初始校验文件,文件名代表类型,检验时读取文件名作为类型判断标准        打开sourse文件夹,读取标准件原始图片,保存标准位置到biaozhun/labels,保存画有标准位置的图片到biaozhun/imgs'''def define_start(img_name, img_path, type):    pts = []  # 用于存放点     def draw_roi(event, x, y, flags, param):        img2 = img.copy()        # print("----------")        # cv2.imshow("img2", img2)        # cv2.waitKey(0)         if event == cv2.EVENT_LBUTTONDOWN:  # 左键点击,选择点            pts.append((x, y))         if event == cv2.EVENT_RBUTTONDOWN:  # 右键点击,取消最近一次选择的点            pts.pop()         if event == cv2.EVENT_MBUTTONDOWN:  # 中键绘制轮廓             cv2.line(img=img2, pt1=pts[0], pt2=pts[-1], color=(255, 0, 0), thickness=2)             for i in range(len(pts)):                txt_save.append("(pt1,pt2):")                txt_save.append(str(pts[i][0]))                txt_save.append(str(pts[i][1]))         if len(pts) > 0:            # 将pts中的最后一点画出来            cv2.circle(img2, pts[-1], 3, (0, 0, 255), -1)         if len(pts) > 1:            # 画线            for i in range(len(pts) - 1):                cv2.circle(img2, pts[i], 5, (0, 0, 255), -1)  # x ,y 为鼠标点击地方的坐标                cv2.line(img=img2, pt1=pts[i], pt2=pts[i + 1], color=(255, 0, 0), thickness=2)            cv2.line(img=img2, pt1=pts[0], pt2=pts[-1], color=(255, 0, 0), thickness=2)         cv2.imshow(WIN_NAME, img2)     def set_ratio(image):        if image is None:            return 0, 0, 0        # print(image.shape)        img_h, img_w = image.shape[:2]        """获取真实的分辨率"""        hDC = win32gui.GetDC(0)        screen_w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES)  # 横向分辨率        screen_h = win32print.GetDeviceCaps(hDC, win32con.DESKTOPVERTRES)  # 纵向分辨率        # print(img_w,img_h)         num_wh = 1        if img_w * img_h > 1.9e7:  # 两千万像素            num_wh = 4        elif img_w * img_h > 1.0e7:  # 一千万像素            num_wh = 3        elif min(img_w, img_h) >= min(screen_w, screen_h) or \                max(img_w, img_h) >= max(screen_w, screen_h):            num_wh = 2        else:            num_wh = 1         ratio_h = int(img_h / num_wh)        ratio_w = int(img_w / num_wh)         return ratio_h, ratio_w, num_wh     (filepath, file) = os.path.split(img_path)     # file = 'r.jpg'      # 需要用户选择图片,传入图片的名称     if file.endswith(".jpg") or file.endswith(".png"):  # 如果file以jpg结尾        # img_dir = os.path.join(file_dir, file)        image = cv2.imread(img_path)         ratio_h, ratio_w, num_wh = set_ratio(image)        if ratio_h == 0 and ratio_w == 0 and num_wh == 0:            print("No image")         txt_path = "./DrawRect/biaozhun/labels/%s.txt" % (img_name)        open(txt_path, 'w').close()  # 清空文件数据        f = open(txt_path, mode='a+')        txt_save = []         img = imutils.resize(image, width = ratio_w)        cv2.namedWindow(WIN_NAME, cv2.WINDOW_NORMAL)        # # cv2.namedWindow(WIN_NAME, 2)        cv2.resizeWindow(WIN_NAME, ratio_w, ratio_h)        cv2.imshow(WIN_NAME, img)        # cv2.waitKey(1)         key = cv2.waitKey(0)         # 矩形        if key == ord("s"):            roi = cv2.selectROI(windowName=WIN_NAME, img=img, showCrosshair=False, fromCenter=False)            x, y, w, h = roi            cv2.rectangle(img=img, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2)             print('pt1: x = %d, y = %d' % (x, y))            txt_save.append("(pt1,pt2):")            txt_save.append(str(x))            txt_save.append(str(y))            txt_save.append(str(x + w))            txt_save.append(str(y + h))             cv2.imshow(WIN_NAME, img)            cv2.waitKey(0)             # 保存txt坐标            num_txt_i = 0            for txt_i in range(len(txt_save)):                txt_i = txt_i - num_txt_i                if txt_save[txt_i] == 'delete':                    for j in range(6):                        del txt_save[txt_i - j]                    num_txt_i += 6            for txt_i in txt_save:                f.write(str(txt_i) + '\n')            print("txt_save:", txt_save)            # break            f.close()             # 查找距离较近的,删除            points_list = get_list0(txt_path)            new_points_list = []            for i in points_list:                x0, y0, x1, y1 = i[0], i[1], i[2], i[3]                if abs(x1 - x0) > 5 and abs(y1 - y0) > 5:                    new_points_list.append('(pt1,pt2):')                    new_points_list.append(x0)                    new_points_list.append(y0)                    new_points_list.append(x1)                    new_points_list.append(y1)            print(new_points_list)            file2 = open(txt_path, 'w')            for i in new_points_list:                file2.write(str(i) + '\n')            file2.close()         # 多边形        elif key == ord("p"):            print("---")             cv2.setMouseCallback(WIN_NAME, draw_roi)             while True:                key = cv2.waitKey(1)                if key == 13 or cv2.getWindowProperty(WIN_NAME, 0) == -1:  # enter回车键:                    # 保存txt坐标                     for i in range(len(pts)):                        txt_save.append("(pt1,pt2):")                        txt_save.append(str(pts[i][0]))                        txt_save.append(str(pts[i][1]))                     num_txt_i = 0                    for txt_i in range(len(txt_save)):                        txt_i = txt_i - num_txt_i                        if txt_save[txt_i] == 'delete':                            for j in range(6):                                del txt_save[txt_i - j]                            num_txt_i += 6                    for txt_i in txt_save:                        f.write(str(txt_i) + '\n')                    print("txt_save:", txt_save)                    # break                    f.close()                 # 现在是多边形之前的方法不行                    # # 查找距离较近的,删除                    # points_list = get_list0(txt_path)                    # new_points_list = []                    # for i in points_list:                    #     x0, y0, x1, y1 = i[0], i[1], i[2], i[3]                    #     if abs(x1 - x0) > 5 and abs(y1 - y0) > 5:                    #         new_points_list.append('(pt1,pt2):')                    #         new_points_list.append(x0)                    #         new_points_list.append(y0)                    #         new_points_list.append(x1)                    #         new_points_list.append(y1)                    # print(new_points_list)                    # file2 = open(txt_path, 'w')                    # for i in new_points_list:                    #     file2.write(str(i) + '\n')                    # file2.close()                     break            cv2.destroyAllWindows()      else:        print("输入图片类型错误!请输入JPG/PNG格式的图片!")   if __name__ == '__main__':    # path_file = open('./datasets/drawPath.json', 'r')    path_file = open('./DataSet/drawPath.json', 'r')    path_dic = json.load(path_file)    img_path = path_dic['path']         # # 绘制标准图片的地址    path_file.close()    img_name = img_path.split('\\')[-1][:-4]    define_start(img_name, img_path, 0)

drawPath.json文件

{"path": "D:\\ALLBuffers\\Pycharm\\OpencvRun\\DataSet\\smpj.jpg"}

2 修改后默认情况下直接画多边形,按鼠标中键切换为画矩形模式

## 1 程序默认运行是直接绘多边形,直接点击即可,## 绘制完成后点击右上角的X或按enter即可关闭图像并保存坐标## 2 在默认情况下,单击鼠标中键或空格即可切换为矩形模式## 3 在绘制矩形模式下只能通过按enter关闭图像并保存坐标## 4 在绘制矩形模式下鼠标左键取消上一步操作或重新绘制矩形## 5 在绘制多边形时鼠标右键取消上一步操作 import copyimport jsonimport joblibimport cv2import numpy as npimport osimport matplotlib.pyplot as pltimport imutilsfrom win32 import win32gui, win32printfrom win32.lib import win32con WIN_NAME = 'draw_rect'  def get_list0(path):    if not os.path.exists(path):        print("记录该型号标准位置的文件缺失/或输入型号与其对应标准文件名称不一致")    file1 = open(path, 'r')    lines = file1.readlines()    # for line in lines:    #     if (any(kw in line for kw in kws)):    #         SeriousFix.write(line + '\n')    zb0, list0 = [], []    for i in range(len(lines)):  # 取坐标        if lines[i] != '(pt1,pt2):\n':            zb0.append(lines[i][:-1])    # print(zb0)    for i in range(0, len(zb0)):  # 转换整数        zb0[i] = int(zb0[i])    # print(zb0)     for i in range(0, len(zb0), 4):  # 每四个取一次,加入列表        x0, y0, x1, y1 = zb0[i: i + 4]         # 使点设为左上至右下        if y1<=y0:            temp = y0            y0 = y1            y1 = temp         # print(x0,y0,x1,y1)        list0.append([x0, y0, x1, y1])    print("list0:", list0)    file1.close()    return list0  '''        初始校验文件,文件名代表类型,检验时读取文件名作为类型判断标准        打开sourse文件夹,读取标准件原始图片,保存标准位置到biaozhun/labels,保存画有标准位置的图片到biaozhun/imgs'''POLYLINES = False  # 多边形向矩形切换  def define_start(img_name, img_path, type):    pts = []  # 用于存放点     def draw_roi(event, x, y, flags, param):         img2 = img.copy()         if event == cv2.EVENT_LBUTTONDOWN:  # 左键点击,选择点            pts.append((x, y))            cv2.circle(img2, pts[-1], 3, (0, 255, 0), -1)        #        # if event == cv2.EVENT_MOUSEMOVE:  # 画圆        #     if len(pts) >= 1:        #         radius = np.sqrt(pow(x-pts[0][0],2) + pow(y-pts[0][1],2))        #         radius = int(radius)        #         rs.append(radius)        #         cv2.circle(img2, pts[0], rs[-1], (0, 0, 255), 2)  # x ,y 为鼠标点击地方的坐标        #          if event == cv2.EVENT_RBUTTONDOWN:  # 右键点击,取消最近一次选择的点            if len(pts) >= 1:                pts.pop()          if event == cv2.EVENT_MBUTTONDOWN:  # 中键绘制轮廓            global POLYLINES            # print("MBUTTONDOWN:  # 中键绘制轮廓")            POLYLINES = True         if len(pts) > 0:            # 将pts中的最后一点画出来            cv2.circle(img2, pts[-1], 3, (0, 255, 0), -1)          if len(pts) > 1:             # 画线            for i in range(len(pts) - 1):                cv2.circle(img2, pts[i], 5, (0, 255, 0), -1)  # x ,y 为鼠标点击地方的坐标                cv2.line(img=img2, pt1=pts[i], pt2=pts[i + 1], color=(0, 0, 255), thickness=2)            cv2.line(img=img2, pt1=pts[0], pt2=pts[-1], color=(0, 0, 255), thickness=2)         cv2.imshow(WIN_NAME, img2)     def set_ratio(image):        if image is None:            return 0, 0, 0        # print(image.shape)        img_h, img_w = image.shape[:2]        """获取真实的分辨率"""        hDC = win32gui.GetDC(0)        screen_w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES)  # 横向分辨率        screen_h = win32print.GetDeviceCaps(hDC, win32con.DESKTOPVERTRES)  # 纵向分辨率        # print(img_w,img_h)         num_wh = 1        if img_w * img_h > 1.9e7:  # 两千万像素            num_wh = 4        elif img_w * img_h > 1.0e7:  # 一千万像素            num_wh = 3        elif min(img_w, img_h) >= min(screen_w, screen_h) or \                max(img_w, img_h) >= max(screen_w, screen_h):            num_wh = 2        else:            num_wh = 1         ratio_h = int(img_h / num_wh)        ratio_w = int(img_w / num_wh)         return ratio_h, ratio_w, num_wh     (filepath, file) = os.path.split(img_path)     # file = 'r.jpg'      # 需要用户选择图片,传入图片的名称     if file.endswith(".jpg") or file.endswith(".png"):  # 如果file以jpg结尾        # img_dir = os.path.join(file_dir, file)        image = cv2.imread(img_path)         ratio_h, ratio_w, num_wh = set_ratio(image)        if ratio_h == 0 and ratio_w == 0 and num_wh == 0:            print("No image")         txt_path = "./DrawRect/biaozhun/labels/%s.txt" % (img_name)        open(txt_path, 'w').close()  # 清空文件数据        f = open(txt_path, mode='a+')        txt_save = []         img = imutils.resize(image, width = ratio_w)        cv2.namedWindow(WIN_NAME, cv2.WINDOW_NORMAL)        cv2.resizeWindow(WIN_NAME, ratio_w, ratio_h)        cv2.imshow(WIN_NAME, img)         # 默认直接执行画多边形        cv2.setMouseCallback(WIN_NAME, draw_roi)         while True:            w_key = cv2.waitKey(1)            # enter 或回车键:            if w_key == 13 or cv2.getWindowProperty(WIN_NAME, 0) == -1:                for i in range(len(pts)):                    if i == 0:                      txt_save.append("(pt1,pt2):")                    txt_save.append(str(pts[i][0]))                    txt_save.append(str(pts[i][1]))                 num_txt_i = 0                for txt_i in range(len(txt_save)):                    txt_i = txt_i - num_txt_i                    if txt_save[txt_i] == 'delete':                        for j in range(6):                            del txt_save[txt_i - j]                        num_txt_i += 6                for txt_i in txt_save:                    f.write(str(txt_i) + '\n')                print("txt_save:", txt_save)                break                f.close()                 # 现在是多边形之前的方法不行                # # 查找距离较近的,删除                # points_list = get_list0(txt_path)                # new_points_list = []                # for i in points_list:                #     x0, y0, x1, y1 = i[0], i[1], i[2], i[3]                #     if abs(x1 - x0) > 5 and abs(y1 - y0) > 5:                #         new_points_list.append('(pt1,pt2):')                #         new_points_list.append(x0)                #         new_points_list.append(y0)                #         new_points_list.append(x1)                #         new_points_list.append(y1)                # print(new_points_list)                # file2 = open(txt_path, 'w')                # for i in new_points_list:                #     file2.write(str(i) + '\n')                # file2.close()             # 空格切换至矩形            if POLYLINES == True or w_key == 32:                roi = cv2.selectROI(windowName=WIN_NAME, img=img, showCrosshair=False, fromCenter=False)                x, y, w, h = roi                cv2.rectangle(img=img, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2)                 print('pt1: x = %d, y = %d' % (x, y))                txt_save.append("(pt1,pt2):")                txt_save.append(str(x))                txt_save.append(str(y))                txt_save.append(str(x + w))                txt_save.append(str(y + h))                 # 用红色框显示ROI                # cv2.imshow(WIN_NAME, img)                # cv2.waitKey(0)                 # 保存txt坐标                num_txt_i = 0                for txt_i in range(len(txt_save)):                    txt_i = txt_i - num_txt_i                    if txt_save[txt_i] == 'delete':                        for j in range(6):                            del txt_save[txt_i - j]                        num_txt_i += 6                for txt_i in txt_save:                    f.write(str(txt_i) + '\n')                print("txt_save:", txt_save)                # break                f.close()                 # 查找距离较近的,删除                points_list = get_list0(txt_path)                new_points_list = []                for i in points_list:                    x0, y0, x1, y1 = i[0], i[1], i[2], i[3]                    if abs(x1 - x0) > 5 and abs(y1 - y0) > 5:                        new_points_list.append('(pt1,pt2):')                        new_points_list.append(x0)                        new_points_list.append(y0)                        new_points_list.append(x1)                        new_points_list.append(y1)                print(new_points_list)                file2 = open(txt_path, 'w')                for i in new_points_list:                    file2.write(str(i) + '\n')                file2.close()                break        cv2.destroyAllWindows()     else:        print("输入图片类型错误!请输入JPG/PNG格式的图片!")  if __name__ == '__main__':    # path_file = open('./datasets/drawPath.json', 'r')    path_file = open('./DataSet/drawPath.json', 'r')    path_dic = json.load(path_file)    img_path = path_dic['path']         # # 绘制标准图片的地址    path_file.close()    img_name = img_path.split('\\')[-1][:-4]    define_start(img_name, img_path, 0)

感谢各位的阅读,以上就是“基于OpenCV如何实现动态画矩形和多边形并保存坐标”的内容了,经过本文的学习后,相信大家对基于OpenCV如何实现动态画矩形和多边形并保存坐标这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于OpenCV如何实现动态画矩形和多边形并保存坐标

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于OpenCV实现动态画矩形和多边形并保存坐标

这篇文章主要为大家详细介绍了如何利用OpenCV实现动态画矩形和多边形并保存坐标,文中的示例代码讲解详细,具有一定的参考价值,需要的可以参考一下
2023-03-23

基于OpenCV如何实现动态画矩形和多边形并保存坐标

这篇文章主要讲解了“基于OpenCV如何实现动态画矩形和多边形并保存坐标”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于OpenCV如何实现动态画矩形和多边形并保存坐标”吧!1 画矩形和多
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录