亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于OpenCV如何實現動態畫矩形和多邊形并保存坐標

發布時間:2023-03-23 14:59:51 來源:億速云 閱讀:132 作者:iii 欄目:開發技術

這篇文章主要講解了“基于OpenCV如何實現動態畫矩形和多邊形并保存坐標”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“基于OpenCV如何實現動態畫矩形和多邊形并保存坐標”吧!

1 畫矩形和多邊形,模式通過鍵盤控制

# 通過鍵盤s和p區別畫矩形和多邊形并保存坐標
# 畫矩形是OPencv自帶的,只能通過按enter結束
 
import copy
import json
import joblib
import cv2
import numpy as np
import os
import matplotlib.pyplot as plt
import imutils
from win32 import win32gui, win32print
from 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
'''
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 copy
import json
import joblib
import cv2
import numpy as np
import os
import matplotlib.pyplot as plt
import imutils
from win32 import win32gui, win32print
from 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如何實現動態畫矩形和多邊形并保存坐標這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宜兴市| 石河子市| 南澳县| 长岭县| 乌拉特后旗| 永新县| 沽源县| 吉木乃县| 耒阳市| 湾仔区| 吴川市| 柞水县| 汪清县| 肃宁县| 浦东新区| 宁津县| 田东县| 洛扎县| 丽江市| 青铜峡市| 阿拉善左旗| 周宁县| 大安市| 新乡市| 灌南县| 丰宁| 封开县| 连江县| 旺苍县| 屏南县| 临洮县| 堆龙德庆县| 云龙县| 抚州市| 海晏县| 盐城市| 安多县| 达尔| 本溪市| 威远县| 麟游县|