您好,登錄后才能下訂單哦!
這篇文章主要介紹了Python怎么對圖像補全并分割成多塊補丁的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Python怎么對圖像補全并分割成多塊補丁文章都會有所收獲,下面我們一起來看看吧。
編寫一個程序,按照輸入的寬高,將測試圖像分割成多個補丁塊,超出圖像邊界的部分用黑色像素補齊
按照輸入的寬高,先判斷原始圖像與其取模是否為零,判斷需不需要進行圖像填充
如果需要進行圖像填充,先計算出新圖像的寬和高((整除后+1)* 指定寬高),然后新建一張全黑圖像,將原圖像默認為左上角位置粘貼進去
最后進行圖像裁剪,使用兩層for循環,步長設定為補丁的寬高,使用crop函數,指定補丁圖片的左、上、右、下坐標
import numpy as np from PIL import Image # 判斷是否需要進行圖像填充 def judge(img, wi, he): width, height = img.size # 默認新圖像尺寸初始化為原圖像 new_width, new_height = img.size if width % wi != 0: new_width = (width//wi + 1) * wi if height % he != 0: new_height = (height//he + 1) * he # 新建一張新尺寸的全黑圖像 new_image = Image.new('RGB', (new_width, new_height), (0, 0, 0)) # 將原圖像粘貼在new_image上,默認為左上角坐標對應 new_image.paste(img, box=None, mask=None) new_image.show() return new_image # 按照指定尺寸進行圖片裁剪 def crop_image(image, patch_w, patch_h): width, height = image.size # 補丁計數 cnt = 0 for w in range(0, width, patch_w): for h in range(0, height, patch_h): cnt += 1 # 指定原圖片的左、上、右、下 img = image.crop((w, h, w+patch_w, h+patch_h)) img.save("dog-%d.jpg" % cnt) print("圖片補丁裁剪結束,共有{}張補丁".format(cnt)) def main(): image_path = "dog.jpg" img = Image.open(image_path) # 查看圖像形狀 print("原始圖像形狀{}".format(np.array(img).shape)) # 輸入指定的補丁寬高 print("輸入補丁寬高:") wi, he = map(int, input().split(" ")) # 進行圖像填充 new_image = judge(img, wi, he) # 圖片補丁裁剪 crop_image(new_image, wi, he) if __name__ == '__main__': main()
原圖像使用了黑色像素填充
圖像裁剪,分割成小補丁
圖像分割是一種常用的圖像處理方法,可分為傳統方法和深度學習的方法。深度學習的方法比如:mask rcnn這類實例分割模型,效果比傳統的圖像分割方法要好的多,所以目前圖像分割領域都是用深度學習來做的。但是深度學習也有它的缺點,模型大、推理速度慢、可解釋性差、訓練數據要求高等。本文在這里僅討論傳統的圖像分割算法,可供學習和使用。
最簡單的圖像分割算法,只直接按照像素值進行分割,雖然簡單,但是在一些像素差別較大的場景中表現不錯,是一種簡單而且穩定的算法。
def thresholdSegment(filename): gray = cv2.imread(filename, cv2.IMREAD_GRAYSCALE) ret1, th2 = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) th3 = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) th4 = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) ret2, th5 = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) images = [th2, th3, th5, th4] imgaesTitle = ['THRESH_BINARY', 'THRESH_MEAN', 'THRESH_OTSU', 'THRESH_GAUSSIAN'] plt.figure() for i in range(4): plt.subplot(2, 2, i+1) plt.imshow(images[i], 'gray') plt.title(imgaesTitle[i]) cv2.imwrite(imgaesTitle[i]+'.jpg', images[i]) plt.show() cv2.waitKey(0) return images
def edgeSegmentation(filename): # 讀取圖片 img = cv2.imread(filename) # 灰度化 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊處理:去噪(效果最好) blur = cv2.GaussianBlur(gray, (9, 9), 0) # Sobel計算XY方向梯度 gradX = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0) gradY = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1) # 計算梯度差 gradient = cv2.subtract(gradX, gradY) # 絕對值 gradient = cv2.convertScaleAbs(gradient) # 高斯模糊處理:去噪(效果最好) blured = cv2.GaussianBlur(gradient, (9, 9), 0) # 二值化 _, dst = cv2.threshold(blured, 90, 255, cv2.THRESH_BINARY) # 滑動窗口 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (107, 76)) # 形態學處理:形態閉處理(腐蝕) closed = cv2.morphologyEx(dst, cv2.MORPH_CLOSE, kernel) # 腐蝕與膨脹迭代 closed = cv2.erode(closed, None, iterations=4) closed = cv2.dilate(closed, None, iterations=4) # 獲取輪廓 _, cnts, _ = cv2.findContours( closed.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) c = sorted(cnts, key=cv2.contourArea, reverse=True)[0] rect = cv2.minAreaRect(c) box = np.int0(cv2.boxPoints(rect)) draw_img = cv2.drawContours(img.copy(), [box], -1, (0, 0, 255), 3) #cv2.imshow("Box", draw_img) #cv2.imwrite('./test/monkey.png', draw_img) images = [blured, dst, closed, draw_img] imgaesTitle = ['blured', 'dst', 'closed', 'draw_img'] plt.figure() for i in range(4): plt.subplot(2, 2, i+1) plt.imshow(images[i], 'gray') plt.title(imgaesTitle[i]) #cv2.imwrite(imgaesTitle[i]+'.jpg', images[i]) plt.show() cv2.waitKey(0)
def regionSegmentation(filename): # 讀取圖片 img = cv2.imread(filename) # 圖片寬度 img_x = img.shape[1] # 圖片高度 img_y = img.shape[0] # 分割的矩形區域 rect = (0, 0, img_x-1, img_y-1) # 背景模式,必須為1行,13x5列 bgModel = np.zeros((1, 65), np.float64) # 前景模式,必須為1行,13x5列 fgModel = np.zeros((1, 65), np.float64) # 圖像掩模,取值有0,1,2,3 mask = np.zeros(img.shape[:2], np.uint8) # grabCut處理,GC_INIT_WITH_RECT模式 cv2.grabCut(img, mask, rect, bgModel, fgModel, 4, cv2.GC_INIT_WITH_RECT) # grabCut處理,GC_INIT_WITH_MASK模式 #cv2.grabCut(img, mask, rect, bgModel, fgModel, 4, cv2.GC_INIT_WITH_MASK) # 將背景0,2設成0,其余設成1 mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8') # 重新計算圖像著色,對應元素相乘 img = img*mask2[:, :, np.newaxis] cv2.imshow("Result", img) cv2.waitKey(0)
def svmSegment(pic): img = Image.open(pic) img.show() # 顯示原始圖像 img_arr = np.asarray(img, np.float64) #選取圖像上的關鍵點RGB值(10個) lake_RGB = np.array( [[147, 168, 125], [151, 173, 124], [143, 159, 112], [150, 168, 126], [146, 165, 120], [145, 161, 116], [150, 171, 130], [146, 112, 137], [149, 169, 120], [144, 160, 111]]) # 選取待分割目標上的關鍵點RGB值(10個) duck_RGB = np.array( [[81, 76, 82], [212, 202, 193], [177, 159, 157], [129, 112, 105], [167, 147, 136], [237, 207, 145], [226, 207, 192], [95, 81, 68], [198, 216, 218], [197, 180, 128]] ) RGB_arr = np.concatenate((lake_RGB, duck_RGB), axis=0) # 按列拼接 # lake 用 0標記,duck用1標記 label = np.append(np.zeros(lake_RGB.shape[0]), np.ones(duck_RGB.shape[0])) # 原本 img_arr 形狀為(m,n,k),現在轉化為(m*n,k) img_reshape = img_arr.reshape( [img_arr.shape[0]*img_arr.shape[1], img_arr.shape[2]]) svc = SVC(kernel='poly', degree=3) # 使用多項式核,次數為3 svc.fit(RGB_arr, label) # SVM 訓練樣本 predict = svc.predict(img_reshape) # 預測測試點 lake_bool = predict == 0. lake_bool = lake_bool[:, np.newaxis] # 增加一列(一維變二維) lake_bool_3col = np.concatenate( (lake_bool, lake_bool, lake_bool), axis=1) # 變為三列 lake_bool_3d = lake_bool_3col.reshape( (img_arr.shape[0], img_arr.shape[1], img_arr.shape[2])) # 變回三維數組(邏輯數組) img_arr[lake_bool_3d] = 255. img_split = Image.fromarray(img_arr.astype('uint8')) # 數組轉image img_split.show() # 顯示分割之后的圖像 img_split.save('split_duck.jpg') # 保存
def watershedSegment(filename): img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # noise removal kernel = np.ones((3,3),np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2) # sure background area sure_bg = cv2.dilate(opening,kernel,iterations=3) # Finding sure foreground area dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0) # Finding unknown region sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(sure_bg,sure_fg) # Marker labelling ret, markers = cv2.connectedComponents(sure_fg) # Add one to all labels so that sure background is not 0, but 1 markers = markers+1 # Now, mark the region of unknown with zero markers[unknown==255]=0 markers = cv2.watershed(img,markers) img[markers == -1] = [255,0,0]
def kmeansSegment(filename,k): f = open(filename,'rb') #二進制打開 data = [] img = Image.open(f) #以列表形式返回圖片像素值 m,n = img.size #圖片大小 for i in range(m): for j in range(n): #將每個像素點RGB顏色處理到0-1范圍內并存放data x,y,z = img.getpixel((i,j)) data.append([x/256.0,y/256.0,z/256.0]) f.close() img_data=np.mat(data) row=m col=n label = KMeans(n_clusters=k).fit_predict(img_data) #聚類中心的個數為3 label = label.reshape([row,col]) #聚類獲得每個像素所屬的類別 pic_new = Image.new("L",(row,col)) #創建一張新的灰度圖保存聚類后的結果 for i in range(row): #根據所屬類別向圖片中添加灰度值 for j in range(col): pic_new.putpixel((i,j),int(256/(label[i][j]+1))) pic_new.save('keans_'+str(k)+'.jpg') plt.imshow(pic_new) plt.show()
關于“Python怎么對圖像補全并分割成多塊補丁”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Python怎么對圖像補全并分割成多塊補丁”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。