python JPG图片手动圈画掩膜Mask轮廓ROI
首先嘗試實現一張JPG圖片的勾畫
注:opencv2鍵鼠操作可參考本博主的文章:python-opencv控制鼠標操作
運行可以得到如下圖窗口 按下鼠標左鍵并移動即可畫圖
注意:若移動過快則會畫出許多點,所以請勿勾畫過快
目前我們只實現了一張圖像的勾畫,怎樣才能實現多張圖像的快速勾畫呢?
比如使用鼠標滾輪快速切換圖像
聽起來很簡單,但也是需要做不少修改的,需要我們理解opencv2窗口、圖像、IO函數的機制,以五張圖像為例,代碼如下(為方便大家理解,未采用循環操作,請大家在自己代碼中自行更改):
由此一來,便實現了滾輪快速切換勾畫圖像的需求。
現在只實現了畫圖而已,MASK掩膜其實是勾畫內部全部為1,外部全部為0的圖像,與原JPG文件并無關系,所以我們需要記錄勾畫的坐標然后找到內部的點并將其置為1,其余置為0
先嘗試記錄下每張圖像勾畫的坐標
import numpy as np import cv2 as cv from matplotlib import pylab as pltnum = 5 now=0 im=[] XY=[] #XY用來存儲五張圖片各自勾畫的坐標 imgs='image'+str(now) for i in range(num):XY.append([])def drawing(event, x, y, flags, param):global imgs #窗口名global now #當前圖片global im #所有圖片if event == 0 and flags == 1: #鼠標移動 and 左鍵按下#注:為了加快運算速度,勾畫時不會存儲本圖片已勾畫過的點if([x,y] not in XY[now]): #若當前點未記錄則添加XY[now].append([x,y])if([x+1,y+1] not in XY[now]):#將當前點與附近的點都添加進勾畫坐標以防止出現間隙XY[now].append([x+1,y+1])if([x-1,y-1] not in XY[now]):XY[now].append([x-1,y-1])if([x+1,y-1] not in XY[now]):XY[now].append([x+1,y-1])if([x-1,y+1] not in XY[now]):XY[now].append([x-1,y+1])if([x+1,y] not in XY[now]):XY[now].append([x+1,y])if([x-1,y] not in XY[now]):XY[now].append([x-1,y])if([x,y+1] not in XY[now]):XY[now].append([x,y+1])if([x,y-1] not in XY[now]):XY[now].append([x,y-1])cv.circle(im[now], (x, y), 1, (71,0, 255), -1)cv.imshow(imgs, im[now])elif event==10: #滾輪cv.destroyAllWindows()if(flags<0): #向下滾now+=1if(now>num-1):now=0imgs='image'+str(now)cv.namedWindow(imgs)cv.moveWindow(imgs,100,100)cv.setMouseCallback(imgs, drawing) cv.imshow(imgs, im[now])else: #向下滾now-=1if(now<0):now=num-1imgs='image'+str(now)cv.namedWindow(imgs)cv.moveWindow(imgs,100,100)cv.setMouseCallback(imgs, drawing) cv.imshow(imgs, im[now])img = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00001.jpg') img2 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00002.jpg') img3 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00003.jpg') img4 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00004.jpg') img5 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00005.jpg') im.append(img) im.append(img2) im.append(img3) im.append(img4) im.append(img5) cv.namedWindow(imgs) cv.moveWindow(imgs,100,100) cv.setMouseCallback(imgs, drawing) cv.imshow(imgs, im[now])cv.waitKey(0) cv.destroyAllWindows()XY數據如下圖所示 其中圖片0 1 2被勾畫 3 4未勾畫
現在我們便成功得到了勾畫坐標,進行一些處理便可以生成MASK掩膜文件
①找到勾畫內部的坐標點
②將圈畫及內部置為1,外部置為0
③優化速度
找到內部坐標點最穩定的方法就是檢測當前點的上下左右是否含有勾畫點,缺點是速度比較慢,但可以通過一些優化大大加快其速度
請注意: 代碼中圖像存儲行列大小與此處分辨率應做調換 詳見代碼及注釋
完整代碼如下:
import numpy as np import cv2 as cv from matplotlib import pylab as pltnum = 5 now=0 im=[] XY=[] imgs='image'+str(now) for i in range(num):XY.append([])#檢測左側是否有勾畫點 def left(ii,jj,l):for i in l:if(i[0]==ii and i[1]<jj):return Truereturn False #檢測右側是否有勾畫點 def right(ii,jj,l):for i in l:if(i[0]==ii and i[1]>jj):return Truereturn False #檢測上側是否有勾畫點 def up(ii,jj,l):for i in l:if(i[1]==jj and i[0]<ii):return Truereturn False #檢測下側是否有勾畫點 def down(ii,jj,l):for i in l:if(i[1]==jj and i[0]>ii):return Truereturn False def drawing(event, x, y, flags, param):global imgsglobal nowglobal imif event == 0 and flags == 1: #鼠標移動 and 左鍵按下if([x,y] not in XY[now]):XY[now].append([x,y])if([x+1,y+1] not in XY[now]):XY[now].append([x+1,y+1])if([x-1,y-1] not in XY[now]):XY[now].append([x-1,y-1])if([x+1,y-1] not in XY[now]):XY[now].append([x+1,y-1])if([x-1,y+1] not in XY[now]):XY[now].append([x-1,y+1])if([x+1,y] not in XY[now]):XY[now].append([x+1,y])if([x-1,y] not in XY[now]):XY[now].append([x-1,y])if([x,y+1] not in XY[now]):XY[now].append([x,y+1])if([x,y-1] not in XY[now]):XY[now].append([x,y-1])cv.circle(im[now], (x, y), 1, (71,0, 255), -1)cv.imshow(imgs, im[now])elif event==10: #滾輪cv.destroyAllWindows()if(flags<0): #向下滾now+=1if(now>num-1):now=0imgs='image'+str(now)cv.namedWindow(imgs)cv.moveWindow(imgs,100,100)cv.setMouseCallback(imgs, drawing) cv.imshow(imgs, im[now])else: #向下滾now-=1if(now<0):now=num-1imgs='image'+str(now)cv.namedWindow(imgs)cv.moveWindow(imgs,100,100)cv.setMouseCallback(imgs, drawing) cv.imshow(imgs, im[now])img = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00001.jpg') img2 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00002.jpg') img3 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00003.jpg') img4 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00004.jpg') img5 = cv.imread(r'C:\Users\Miao\Desktop\T1jpg\IMG-0003-00005.jpg') im.append(img) im.append(img2) im.append(img3) im.append(img4) im.append(img5) cv.namedWindow(imgs) cv.moveWindow(imgs,100,100) cv.setMouseCallback(imgs, drawing) cv.imshow(imgs, im[now])cv.waitKey(0) cv.destroyAllWindows()img_size = [260, 320, 3] #根據自己的JPG圖像修改前兩個數據大小 與分辨率調換行列for l in XY: #依次處理每張圖片的勾畫if(l):#若本圖有勾畫信息img2 = np.zeros(img_size, np.uint16)#先生成同型的全0數據for m in l: img2[m[1]][m[0]]=[1,1,1]#若想可視化,請修改為[255,255,255],但掩膜文件應全為1,方便后續處理iii=0jjj=0start=0 #當前行是否有勾畫 for i in img2:jjj=0if(right(iii,jjj,l) or left(iii,jjj,l) or up(iii,jjj,l) or down(iii,jjj,l)):start=1 #若當前行有勾畫則處理本行if(start):for j in i:if(right(iii,jjj,l) and left(iii,jjj,l) and up(iii,jjj,l) and down(iii,jjj,l)):img2[jjj][iii]=[1,1,1] #注:若想可視化請修改為[255,255,255],但制作掩膜需要使用[1,1,1]jjj+=1start=0iii+=1#若需要可視化 請先將代碼中[1,1,1]修改為[255,255,255] #plt.figure(figsize=(26, 32))#ax = plt.subplot(3,1,1)#ax.imshow(img2)#ax.axis("off")若將代碼中[1,1,1]修改為[255,255,255]并取消最后四行的注釋則可進行可視化
總結
以上是生活随笔為你收集整理的python JPG图片手动圈画掩膜Mask轮廓ROI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 修改pkg命令,Oracl
- 下一篇: Python采集CSDN博客排行榜数据