剪切图片黑边(黑边含有噪点)
程序员文章站
2022-05-21 09:29:35
...
剪切图片黑边(黑边含有噪点)
一般的思路是,当黑边没有噪点的时候可以直接将图片转化为二值图,找到所有=255的点,然后x、y两个轴上分别取最大和最小值我们就可以确定一个目标的区域范围了,之后进行剪切即可,这种方式网上有很多例子,不再赘述。
但是当黑边中存在连成片的噪点时,这个方法会导致图片截取的区域范围增大。就比如下面这张图(颜色通道不是RGB看起来有点怪>。<不影响结果),蓝色粗线条将所有的连通域都画出来了,如果用上面说的那种做法的话,我们会得到红色框圈出来的部分,而不是想要的照片区域。
如果我们像要得到中间蓝色圈圈部分怎么办呢,可以将小的连通区域填充为背景色黑色,然后再进行刚才的操作。
import cv2
import os,numpy as np
import time
def cut_pic(file_name):
img = cv2.imread(file_name)
h, w, _ = img.shape
GrayImage = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #图片灰度化处理
ret,binary = cv2.threshold(GrayImage,15,255,cv2.THRESH_BINARY) #图片二值化,灰度值大于40赋值255,反之0
threshold = 10 #噪点阈值
contours,hierarch=cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
# 填充彩图,再次转化为二值图进行其他操作,麻烦
'''
for i in range(len(contours)):
area = cv2.contourArea(contours[i]) #计算轮廓所占面积
if area < threshold: #将area小于阈值区域填充背景色
cv2.drawContours(img,[contours[i]],-1, (0,0,0), thickness=-1) #原始图片背景BGR值(0,0,0)
continue
binary_image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转为灰度图
_, binary_image = cv2.threshold(binary, 15, 255, cv2.THRESH_BINARY) #二值化
'''
# 直接填充二值图
for i in range(len(contours)):
area = cv2.contourArea(contours[i]) #计算轮廓所占面积
if area < threshold: #将area小于阈值区域填充背景色
cv2.drawContours(binary, [contours[i]],-1, 0, thickness=-1) #原始图片背景0
continue
print(binary.shape,end=' ')
#得到所有目标点 横坐标、纵坐标
edges_x,edges_y = np.where(binary==255)
top = min(edges_x) #上边界
bottom = max(edges_x) #下边界
height= bottom - top #高度
left = min(edges_y) #左边界
right = max(edges_y) #右边界
width = right - left #宽度
print((height,width))
#返回剪切后的图
return img[top:top+height,left:left+width]
source_path="./Training_Set/Training/" #图片来源路径
#图片修改后的保存路径
starttime=time.time()
for i in range(1,1000):
print("裁剪:",str(i) + '.png',end=' ')
img = cut_pic(source_path + str(i) + '.png' ) #得到文件名
save_path="./Training_Set/"+str(shape[0])+'x'+str(shape[1])+'/'
if not os.path.exists(save_path):
os.mkdir(save_path)
cv2.imwrite(save_path + str(i) + '.png',img)
if i % 50 == 0:
print("+++++++裁剪数量:",i,'++++++++')
print("裁剪完毕")
endtime = time.time()#记录结束时间
print("裁剪总用时%d s" % (endtime-starttime))
推荐阅读