




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第Python如何對圖像補全并分割成多塊補丁目錄題目思路代碼效果展示圖像分割方法總結1、閾值分割2、邊界分割(邊緣檢測)3、區域分割(區域生成)4、SVM分割(支持向量機)5、分水嶺分割6、Kmeans分割
題目
編寫一個程序,按照輸入的寬高,將測試圖像分割成多個補丁塊,超出圖像邊界的部分用黑色像素補齊
思路
按照輸入的寬高,先判斷原始圖像與其取模是否為零,判斷需不需要進行圖像填充
如果需要進行圖像填充,先計算出新圖像的寬和高((整除后+1)*指定寬高),然后新建一張全黑圖像,將原圖像默認為左上角位置粘貼進去
最后進行圖像裁剪,使用兩層for循環,步長設定為補丁的寬高,使用crop函數,指定補丁圖片的左、上、右、下坐標
代碼
importnumpyasnp
fromPILimportImage
#判斷是否需要進行圖像填充
defjudge(img,wi,he):
width,height=img.size
#默認新圖像尺寸初始化為原圖像
new_width,new_height=img.size
ifwidth%wi!=0:
new_width=(width//wi+1)*wi
ifheight%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()
returnnew_image
#按照指定尺寸進行圖片裁剪
defcrop_image(image,patch_w,patch_h):
width,height=image.size
#補丁計數
cnt=0
forwinrange(0,width,patch_w):
forhinrange(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))
defmain():
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()
效果展示
原圖像使用了黑色像素填充
圖像裁剪,分割成小補丁
圖像分割方法總結
圖像分割是一種常用的圖像處理方法,可分為傳統方法和深度學習的方法。深度學習的方法比如:maskrcnn這類實例分割模型,效果比傳統的圖像分割方法要好的多,所以目前圖像分割領域都是用深度學習來做的。但是深度學習也有它的缺點,模型大、推理速度慢、可解釋性差、訓練數據要求高等。本文在這里僅討論傳統的圖像分割算法,可供學習和使用。
1、閾值分割
最簡單的圖像分割算法,只直接按照像素值進行分割,雖然簡單,但是在一些像素差別較大的場景中表現不錯,是一種簡單而且穩定的算法。
defthresholdSegment(filename):
gray=cv2.imread(filename,cv2.IMREAD_GRAYSCALE)
ret1,th1=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
th2=cv2.adaptiveThreshold(
gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
th3=cv2.adaptiveThreshold(
gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
ret2,th4=cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
images=[th1,th2,th4,th3]
imgaesTitle=['THRESH_BINARY','THRESH_MEAN',
'THRESH_OTSU','THRESH_GAUSSIAN']
plt.figure()
foriinrange(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)
returnimages
2、邊界分割(邊緣檢測)
defedgeSegmentation(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=0(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()
foriinrange(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)
3、區域分割(區域生成)
defregionSegmentation(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)
4、SVM分割(支持向量機)
defsvmSegment(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')
#保存
5、分水嶺分割
defwatershedSegment(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)
#noiseremoval
kernel=np.ones((3,3),np.uint8)
opening=cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2)
#surebackgroundarea
sure_bg=cv2.dilate(opening,kernel,iterations=3)
#Findingsureforegroundarea
dist_transform=cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret,sure_fg=cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
#Findingunknownregion
sure_fg=np.uint8(sure_fg)
unknown=cv2.subtract(sure_bg,sure_fg)
#Markerlabelling
ret,markers=cv2.connectedComponents(sure_fg)
#Addonetoalllabelssothatsurebackgroundisnot0,but1
markers=markers+1
#Now,marktheregionofunknownwithzero
markers[unknown==255]=0
markers=cv2.watershed(img,markers)
i
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二手房買賣合同違約責任追究協議
- 財務報表風險敞口應對效果評估合同
- 材料疲勞斷裂數據校正合同
- 生態農業園區場地合作經營與產品銷售協議
- 邊疆地區古代商業貿易考古合同
- 高端裝備制造廠房租賃與智能化改造協議
- 大學刑法考試題及答案
- 群體健康策略課件
- 調研安全生產工作方案
- 安全總監個人述職報告3
- 2024年廣東省中考物理試卷(含答案逐題解析)
- 武術專業個人簡歷模板范文
- LD水電站智慧工程建設方案研究
- DB37-T 4384-2021 混凝土橋梁有效預應力無損檢測技術規程
- 竣工財務決算報表模板
- 2021利達JB-QG-LD988EL JB-QT-LD988EL 火災報警控制器 消防聯動控制器調試手冊
- 2024年中鐵(天津)軌道交通投資建設限公司運營管理人員招聘5人高頻考題難、易錯點模擬試題(共500題)附帶答案詳解
- 創傷中心匯報
- 裝配式結構吊裝施工計算書
- 2024安徽蕪湖市中江城建集團限公司下屬子公司社會招聘60人公開引進高層次人才和急需緊缺人才筆試參考題庫(共500題)答案詳解版
- 放射科疑難病例分析討論記錄
評論
0/150
提交評論