基于OpenCV實(shí)現(xiàn)動(dòng)態(tài)畫(huà)矩形和多邊形并保存坐標(biāo)
現(xiàn)在畫(huà)矩形和多邊形一次只能畫(huà)一個(gè),還需要修改讓其一次可畫(huà)多個(gè)?
1 畫(huà)矩形和多邊形,模式通過(guò)鍵盤(pán)控制
# 通過(guò)鍵盤(pán)s和p區(qū)別畫(huà)矩形和多邊形并保存坐標(biāo) # 畫(huà)矩形是OPencv自帶的,只能通過(guò)按enter結(jié)束 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("記錄該型號(hào)標(biāo)準(zhǔn)位置的文件缺失/或輸入型號(hào)與其對(duì)應(yīng)標(biāo)準(zhǔn)文件名稱不一致") 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)): # 取坐標(biāo) if lines[i] != '(pt1,pt2):\n': zb0.append(lines[i][:-1]) # print(zb0) for i in range(0, len(zb0)): # 轉(zhuǎn)換整數(shù) zb0[i] = int(zb0[i]) # print(zb0) for i in range(0, len(zb0), 4): # 每四個(gè)取一次,加入列表 x0, y0, x1, y1 = zb0[i: i + 4] # 使點(diǎn)設(shè)為左上至右下 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 ''' 初始校驗(yàn)文件,文件名代表類型,檢驗(yàn)時(shí)讀取文件名作為類型判斷標(biāo)準(zhǔn) 打開(kāi)sourse文件夾,讀取標(biāo)準(zhǔn)件原始圖片,保存標(biāo)準(zhǔn)位置到biaozhun/labels,保存畫(huà)有標(biāo)準(zhǔn)位置的圖片到biaozhun/imgs ''' def define_start(img_name, img_path, type): pts = [] # 用于存放點(diǎn) def draw_roi(event, x, y, flags, param): img2 = img.copy() # print("----------") # cv2.imshow("img2", img2) # cv2.waitKey(0) if event == cv2.EVENT_LBUTTONDOWN: # 左鍵點(diǎn)擊,選擇點(diǎn) pts.append((x, y)) if event == cv2.EVENT_RBUTTONDOWN: # 右鍵點(diǎn)擊,取消最近一次選擇的點(diǎn) 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中的最后一點(diǎn)畫(huà)出來(lái) cv2.circle(img2, pts[-1], 3, (0, 0, 255), -1) if len(pts) > 1: # 畫(huà)線 for i in range(len(pts) - 1): cv2.circle(img2, pts[i], 5, (0, 0, 255), -1) # x ,y 為鼠標(biāo)點(diǎn)擊地方的坐標(biāo) 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] """獲取真實(shí)的分辨率""" 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: # 兩千萬(wàn)像素 num_wh = 4 elif img_w * img_h > 1.0e7: # 一千萬(wàn)像素 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結(jié)尾 # 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() # 清空文件數(shù)據(jù) 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坐標(biāo) 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坐標(biāo) 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() # 現(xiàn)在是多邊形之前的方法不行 # # 查找距離較近的,刪除 # 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("輸入圖片類型錯(cuò)誤!請(qǐng)輸入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'] # # 繪制標(biāo)準(zhǔn)圖片的地址 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 修改后默認(rèn)情況下直接畫(huà)多邊形,按鼠標(biāo)中鍵切換為畫(huà)矩形模式
## 1 程序默認(rèn)運(yùn)行是直接繪多邊形,直接點(diǎn)擊即可, ## 繪制完成后點(diǎn)擊右上角的X或按enter即可關(guān)閉圖像并保存坐標(biāo) ## 2 在默認(rèn)情況下,單擊鼠標(biāo)中鍵或空格即可切換為矩形模式 ## 3 在繪制矩形模式下只能通過(guò)按enter關(guān)閉圖像并保存坐標(biāo) ## 4 在繪制矩形模式下鼠標(biāo)左鍵取消上一步操作或重新繪制矩形 ## 5 在繪制多邊形時(shí)鼠標(biāo)右鍵取消上一步操作 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("記錄該型號(hào)標(biāo)準(zhǔn)位置的文件缺失/或輸入型號(hào)與其對(duì)應(yīng)標(biāo)準(zhǔn)文件名稱不一致") 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)): # 取坐標(biāo) if lines[i] != '(pt1,pt2):\n': zb0.append(lines[i][:-1]) # print(zb0) for i in range(0, len(zb0)): # 轉(zhuǎn)換整數(shù) zb0[i] = int(zb0[i]) # print(zb0) for i in range(0, len(zb0), 4): # 每四個(gè)取一次,加入列表 x0, y0, x1, y1 = zb0[i: i + 4] # 使點(diǎn)設(shè)為左上至右下 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 ''' 初始校驗(yàn)文件,文件名代表類型,檢驗(yàn)時(shí)讀取文件名作為類型判斷標(biāo)準(zhǔn) 打開(kāi)sourse文件夾,讀取標(biāo)準(zhǔn)件原始圖片,保存標(biāo)準(zhǔn)位置到biaozhun/labels,保存畫(huà)有標(biāo)準(zhǔn)位置的圖片到biaozhun/imgs ''' POLYLINES = False # 多邊形向矩形切換 def define_start(img_name, img_path, type): pts = [] # 用于存放點(diǎn) def draw_roi(event, x, y, flags, param): img2 = img.copy() if event == cv2.EVENT_LBUTTONDOWN: # 左鍵點(diǎn)擊,選擇點(diǎn) pts.append((x, y)) cv2.circle(img2, pts[-1], 3, (0, 255, 0), -1) # # if event == cv2.EVENT_MOUSEMOVE: # 畫(huà)圓 # 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 為鼠標(biāo)點(diǎn)擊地方的坐標(biāo) # if event == cv2.EVENT_RBUTTONDOWN: # 右鍵點(diǎn)擊,取消最近一次選擇的點(diǎn) if len(pts) >= 1: pts.pop() if event == cv2.EVENT_MBUTTONDOWN: # 中鍵繪制輪廓 global POLYLINES # print("MBUTTONDOWN: # 中鍵繪制輪廓") POLYLINES = True if len(pts) > 0: # 將pts中的最后一點(diǎn)畫(huà)出來(lái) cv2.circle(img2, pts[-1], 3, (0, 255, 0), -1) if len(pts) > 1: # 畫(huà)線 for i in range(len(pts) - 1): cv2.circle(img2, pts[i], 5, (0, 255, 0), -1) # x ,y 為鼠標(biāo)點(diǎn)擊地方的坐標(biāo) 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] """獲取真實(shí)的分辨率""" 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: # 兩千萬(wàn)像素 num_wh = 4 elif img_w * img_h > 1.0e7: # 一千萬(wàn)像素 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結(jié)尾 # 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() # 清空文件數(shù)據(jù) 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) # 默認(rèn)直接執(zhí)行畫(huà)多邊形 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() # 現(xiàn)在是多邊形之前的方法不行 # # 查找距離較近的,刪除 # 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坐標(biāo) 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("輸入圖片類型錯(cuò)誤!請(qǐng)輸入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'] # # 繪制標(biāo)準(zhǔn)圖片的地址 path_file.close() img_name = img_path.split('\\')[-1][:-4] define_start(img_name, img_path, 0)
以上就是基于OpenCV實(shí)現(xiàn)動(dòng)態(tài)畫(huà)矩形和多邊形并保存坐標(biāo)的詳細(xì)內(nèi)容,更多關(guān)于OpenCV動(dòng)態(tài)畫(huà)矩形 多邊形的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 基于OpenCV和Gradio實(shí)現(xiàn)簡(jiǎn)單的人臉識(shí)別詳解
- 在樹(shù)莓派2或樹(shù)莓派B+上安裝Python和OpenCV的教程
- 樹(shù)莓派極簡(jiǎn)安裝OpenCv的方法步驟
- visual studio 2012安裝配置方法圖文教程 附opencv配置教程
- windows下Pycharm安裝opencv的多種方法
- nodejs安裝與配置過(guò)程+初學(xué)實(shí)例解讀
- node-gyp安裝vuetify編譯失敗gyp?ERR的問(wèn)題及解決
- 安裝nvm并使用nvm安裝nodejs及配置環(huán)境變量的全過(guò)程
- window系統(tǒng) nodejs安裝opencv環(huán)境配置圖文詳解
相關(guān)文章
解決Python中l(wèi)ist里的中文輸出到html模板里的問(wèn)題
今天小編就為大家分享一篇解決Python中l(wèi)ist里的中文輸出到html模板里的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12pyqt5之將textBrowser的內(nèi)容寫(xiě)入txt文檔的方法
今天小編就為大家分享一篇pyqt5之將textBrowser的內(nèi)容寫(xiě)入txt文檔的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06python wav模塊獲取采樣率 采樣點(diǎn)聲道量化位數(shù)(實(shí)例代碼)
這篇文章主要介紹了python wav模塊獲取采樣率 采樣點(diǎn)聲道量化位數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01django中的數(shù)據(jù)庫(kù)遷移的實(shí)現(xiàn)
這篇文章主要介紹了django中的數(shù)據(jù)庫(kù)遷移的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03