Python怎么对图像补全并分割成多块补丁
发表于:2025-02-22 作者:千家信息网编辑
千家信息网最后更新 2025年02月22日,这篇文章主要介绍了Python怎么对图像补全并分割成多块补丁的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python怎么对图像补全并分割成多块补丁文章都会有所收获,下面
千家信息网最后更新 2025年02月22日Python怎么对图像补全并分割成多块补丁
这篇文章主要介绍了Python怎么对图像补全并分割成多块补丁的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python怎么对图像补全并分割成多块补丁文章都会有所收获,下面我们一起来看看吧。
题目
编写一个程序,按照输入的宽高,将测试图像分割成多个补丁块,超出图像边界的部分用黑色像素补齐
思路
按照输入的宽高,先判断原始图像与其取模是否为零,判断需不需要进行图像填充
如果需要进行图像填充,先计算出新图像的宽和高((整除后+1)* 指定宽高),然后新建一张全黑图像,将原图像默认为左上角位置粘贴进去
最后进行图像裁剪,使用两层for循环,步长设定为补丁的宽高,使用crop函数,指定补丁图片的左、上、右、下坐标
代码
import numpy as npfrom 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这类实例分割模型,效果比传统的图像分割方法要好的多,所以目前图像分割领域都是用深度学习来做的。但是深度学习也有它的缺点,模型大、推理速度慢、可解释性差、训练数据要求高等。本文在这里仅讨论传统的图像分割算法,可供学习和使用。
1、阈值分割
最简单的图像分割算法,只直接按照像素值进行分割,虽然简单,但是在一些像素差别较大的场景中表现不错,是一种简单而且稳定的算法。
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
2、边界分割(边缘检测)
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)
3、区域分割(区域生成)
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)
4、SVM分割(支持向量机)
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') # 保存
5、分水岭分割
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]
6、Kmeans分割
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怎么对图像补全并分割成多块补丁"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。
图像
补丁
图片
处理
像素
方法
学习
成多
原图
效果
模式
深度
输入
原始
传统
区域
尺寸
形状
数组
灰度
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全监测预警机制
斗罗大陆武魂觉醒怎么更换服务器
我的世界 魔法服务器
我的世界冒险岛服务器群号
网络安全法的网络数据指
甘肃超频服务器联系人
赴日软件开发日语面试问题
文件存储服务器配置和ad域
数据库运维工作是什么
网络安全教育班会作文
杭州应用软件开发哪家有实力
pdb蛋白质数据库属于
中国移动软件开发公司
浙江苍穹互联网科技
常州浪潮服务器维修电话
湖北app软件开发报价
上海智能化软件开发定制大概费用
网站数据库 ftp
日照市网络安全应急服务支撑单位
饥荒云服务器为什么卡顿
还原iphone无法联系服务器
改数据库密码
合肥在线教育平台软件开发公司
饥荒加别人的服务器闪退
网络安全评估机构
微软数据库自动安装
btso 数据库
苹果手机网络安全教学
网络技术科可以找人吗
模拟器如何选择服务器