Python如何对图像补全并分割成多块补丁_第1页
Python如何对图像补全并分割成多块补丁_第2页
Python如何对图像补全并分割成多块补丁_第3页
Python如何对图像补全并分割成多块补丁_第4页
Python如何对图像补全并分割成多块补丁_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论