Python如何對(duì)圖像補(bǔ)全并分割成多塊補(bǔ)丁_第1頁
Python如何對(duì)圖像補(bǔ)全并分割成多塊補(bǔ)丁_第2頁
Python如何對(duì)圖像補(bǔ)全并分割成多塊補(bǔ)丁_第3頁
Python如何對(duì)圖像補(bǔ)全并分割成多塊補(bǔ)丁_第4頁
Python如何對(duì)圖像補(bǔ)全并分割成多塊補(bǔ)丁_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第Python如何對(duì)圖像補(bǔ)全并分割成多塊補(bǔ)丁目錄題目思路代碼效果展示圖像分割方法總結(jié)1、閾值分割2、邊界分割(邊緣檢測(cè))3、區(qū)域分割(區(qū)域生成)4、SVM分割(支持向量機(jī))5、分水嶺分割6、Kmeans分割

題目

編寫一個(gè)程序,按照輸入的寬高,將測(cè)試圖像分割成多個(gè)補(bǔ)丁塊,超出圖像邊界的部分用黑色像素補(bǔ)齊

思路

按照輸入的寬高,先判斷原始圖像與其取模是否為零,判斷需不需要進(jìn)行圖像填充

如果需要進(jìn)行圖像填充,先計(jì)算出新圖像的寬和高((整除后+1)*指定寬高),然后新建一張全黑圖像,將原圖像默認(rèn)為左上角位置粘貼進(jìn)去

最后進(jìn)行圖像裁剪,使用兩層for循環(huán),步長設(shè)定為補(bǔ)丁的寬高,使用crop函數(shù),指定補(bǔ)丁圖片的左、上、右、下坐標(biāo)

代碼

importnumpyasnp

fromPILimportImage

#判斷是否需要進(jìn)行圖像填充

defjudge(img,wi,he):

width,height=img.size

#默認(rèn)新圖像尺寸初始化為原圖像

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上,默認(rèn)為左上角坐標(biāo)對(duì)應(yīng)

new_image.paste(img,box=None,mask=None)

new_image.show()

returnnew_image

#按照指定尺寸進(jìn)行圖片裁剪

defcrop_image(image,patch_w,patch_h):

width,height=image.size

#補(bǔ)丁計(jì)數(shù)

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("圖片補(bǔ)丁裁剪結(jié)束,共有{}張補(bǔ)丁".format(cnt))

defmain():

image_path="dog.jpg"

img=Image.open(image_path)

#查看圖像形狀

print("原始圖像形狀{}".format(np.array(img).shape))

#輸入指定的補(bǔ)丁寬高

print("輸入補(bǔ)丁寬高:")

wi,he=map(int,input().split(""))

#進(jìn)行圖像填充

new_image=judge(img,wi,he)

#圖片補(bǔ)丁裁剪

crop_image(new_image,wi,he)

if__name__=='__main__':

main()

效果展示

原圖像使用了黑色像素填充

圖像裁剪,分割成小補(bǔ)丁

圖像分割方法總結(jié)

圖像分割是一種常用的圖像處理方法,可分為傳統(tǒng)方法和深度學(xué)習(xí)的方法。深度學(xué)習(xí)的方法比如:maskrcnn這類實(shí)例分割模型,效果比傳統(tǒng)的圖像分割方法要好的多,所以目前圖像分割領(lǐng)域都是用深度學(xué)習(xí)來做的。但是深度學(xué)習(xí)也有它的缺點(diǎn),模型大、推理速度慢、可解釋性差、訓(xùn)練數(shù)據(jù)要求高等。本文在這里僅討論傳統(tǒng)的圖像分割算法,可供學(xué)習(xí)和使用。

1、閾值分割

最簡單的圖像分割算法,只直接按照像素值進(jìn)行分割,雖然簡單,但是在一些像素差別較大的場景中表現(xiàn)不錯(cuò),是一種簡單而且穩(wěn)定的算法。

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、邊界分割(邊緣檢測(cè))

defedgeSegmentation(filename):

#讀取圖片

img=cv2.imread(filename)

#灰度化

gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#高斯模糊處理:去噪(效果最好)

blur=cv2.GaussianBlur(gray,(9,9),0)

#Sobel計(jì)算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)

#計(jì)算梯度差

gradient=cv2.subtract(gradX,gradY)

#絕對(duì)值

gradient=cv2.convertScaleAbs(gradient)

#高斯模糊處理:去噪(效果最好)

blured=cv2.GaussianBlur(gradient,(9,9),0)

#二值化

_,dst=cv2.threshold(blured,90,255,cv2.THRESH_BINARY)

#滑動(dòng)窗口

kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(107,76))

#形態(tài)學(xué)處理:形態(tài)閉處理(腐蝕)

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、區(qū)域分割(區(qū)域生成)

defregionSegmentation(filename):

#讀取圖片

img=cv2.imread(filename)

#圖片寬度

img_x=img.shape[1]

#圖片高度

img_y=img.shape[0]

#分割的矩形區(qū)域

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設(shè)成0,其余設(shè)成1

mask2=np.where((mask==2)|(mask==0),0,1).astype('uint8')

#重新計(jì)算圖像著色,對(duì)應(yīng)元素相乘

img=img*mask2[:,:,np.newaxis]

cv2.imshow("Result",img)

cv2.waitKey(0)

4、SVM分割(支持向量機(jī))

defsvmSegment(pic):

img=Image.open(pic)

img.show()

#顯示原始圖像

img_arr=np.asarray(img,np.float64)

#選取圖像上的關(guān)鍵點(diǎn)RGB值(10個(gè))

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]])

#選取待分割目標(biāo)上的關(guān)鍵點(diǎn)RGB值(10個(gè))

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標(biāo)記,duck用1標(biāo)記

label=np.append(np.zeros(lake_RGB.shape[0]),np.ones(duck_RGB.shape[0]))

#原本img_arr形狀為(m,n,k),現(xiàn)在轉(zhuǎn)化為(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)

#使用多項(xiàng)式核,次數(shù)為3

svc.fit(RGB_arr,label)

#SVM訓(xùn)練樣本

predict=svc.predict(img_reshape)

#預(yù)測(cè)測(cè)試點(diǎn)

lake_bool=predict==0.

lake_bool=lake_bool[:,np.newaxis]

#增加一列(一維變二維)

lake_bool_3col=np.concatenate(

(lake_bool,lake_bool,lake_bool),axis=1)

#變?yōu)槿?/p>

lake_bool_3d=lake_bool_3col.reshape(

(img_arr.shape[0],img_arr.shape[1],img_arr.shape[2]))

#變回三維數(shù)組(邏輯數(shù)組)

img_arr[lake_bool_3d]=255.

img_split=Image.fromarray(img_arr.astype('uint8'))

#數(shù)組轉(zhuǎn)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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論