python-3.x - 如何使用python一次从一个文件夹中裁剪多个图像?
问题描述
我有这个代码
但是我很难以某种模式标记每个图像的补丁,例如我有一个名为 000_train 的图像,现在它的补丁应该命名为 000_train_00...... 000_train_01 等等或对于 671_train 它的补丁应该是 671_train_00.......671_train_01 等等
所以我有 671 张图像,所以每个图像补丁应该具有唯一标识其原始图像的名称,但同时自动将每个图像裁剪图像分别存储在单独的文件夹中,名称分别为 0,1.......
import numpy as np
import cv2
import glob
from os import listdir
from os.path import isfile, join
from PIL import Image
import os
#look_up_table={"Ab":"0","An":"1","Di":"2","He":"3","Is":"4","Ky":"5","Kyr":"6","Me":"7","Pi":"8","Vi":"9"}
path = r"C:/Users/55/.spyder-py3/IAM/Train/"
save_path = "C:/Users/55/.spyder-py3/IAM/train_patches/"
# path = r"C:/Users/55/.spyder-py3/IAM/Test/"
# save_path = "C:/Users/55/.spyder-py3/IAM/test_patches/"
image_files = [f for f in os.listdir(path) if f.endswith('.png')]
def load_labels(path):
labels=[]
fileList = glob.glob(os.path.join(path,"*.png"))
for fname in fileList:
fileName=os.path.basename(fname)
curLabel=fileName
labels.append(curLabel)
return np.asarray(labels)
def load_data(path):
fileList=glob.glob(path)
x=np.array([np.array(Image.open(fname)).flatten() for fname in fileList])
x=x/255 #img size grey scale
return x
def imcrop(img, bbox):
x1,y1,x2,y2 = bbox
if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
return img[y1:y2, x1:x2, :]
def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
img = np.pad(img, ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
(np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)), (0,0)), mode="constant")
y1 += np.abs(np.minimum(0, y1))
y2 += np.abs(np.minimum(0, y1))
x1 += np.abs(np.minimum(0, x1))
x2 += np.abs(np.minimum(0, x1))
return img, x1, x2, y1, y2
for file in image_files:
w=0
sample_image = cv2.imread(path+str(file))
# get dimensions of image
dimensions = sample_image.shape
# height, width, number of channels in image
height = sample_image.shape[0]
width = sample_image.shape[1]
channels = sample_image.shape[2]
print('Image Dimension : ',dimensions)
print('Image Height : ',height)
print('Image Width : ',width)
print('Number of Channels : ',channels)
window_width=500
window_height=500
writer = file.split("fileName")[0]
#writer = load_labels(path)
for i in range(0,height,window_height):
for j in range(0,width,window_width):
# for temp in writer:
# if crop_image==window_width && window_height
crop_image = sample_image[i:i+window_height,j:j+window_width]
cv2.imwrite(save_path+str(writer)+"_"+str(w)+".png",crop_image)
w=w+1
#else
#
解决方案
通过以下更改,您的代码可以实现您想要实现的目标:
[...]
path = 'images/'
save_path = "train_patches/"
image_files = [f for f in os.listdir(path) if f.endswith('.jpg')]
#w=0 # <-- Moved w=0 from here...
[...]
for file in image_files:
w=0 # <-- ... to here
[...]
writer = file.split('.')[0] # <-- Split at . to get rid of the file extension
#writer = load_labels(path) # <-- Why?
for i in range(0,height,window_height):
for j in range(0,width,window_width):
#for image_files in writer: # <-- Why?
crop_image = sample_image[i:i+window_height,j:j+window_width]
cv2.imwrite(save_path+str(writer)+"_"+str(w)+".png",crop_image)
w=w+1
所以,既然你正在迭代所有文件
for file in image_files:
您必须w=0
在此循环内重置,以便您的补丁计数器从0
每个图像开始。剩下的就是在没有文件扩展名的情况下获得正确的文件名。Cave at:肯定有更好的方法可以做到这一点,但上述更改是对现有代码的最小更改。
希望有帮助!
编辑:这是一个包含更改/附加主题的最小示例:
import cv2
import os
path = 'images/'
save_path = 'train_patches/'
if not os.path.isdir(save_path):
os.mkdir(save_path)
image_files = [f for f in os.listdir(path) if f.endswith('.jpg')]
for file in image_files:
w = 0
sample_image = cv2.imread(path + str(file))
height = sample_image.shape[0]
width = sample_image.shape[1]
window_width = 500
window_height = 500
writer = file.split('.')[0]
if not os.path.isdir(save_path + '/' + writer + '/'):
os.mkdir(save_path + '/' + writer + '/')
for i in range(0, height, window_height):
for j in range(0, width, window_width):
crop_image = sample_image[i:i+window_height, j:j+window_width]
cv2.imwrite(save_path + '/' + writer + '/' + str(w) + '.png', crop_image)
w = w + 1
for root, dirs, files in os.walk(save_path):
path = root.split(os.sep)
print((len(path) - 1) * '---', os.path.basename(root))
for file in files:
print(len(path) * '---', file)
输出:
another_jpg_image
--- 0.png
--- 1.png
--- 10.png
--- 11.png
--- 2.png
--- 3.png
--- 4.png
--- 5.png
--- 6.png
--- 7.png
--- 8.png
--- 9.png
a_jpg_image
--- 0.png
--- 1.png
the_last_jpg_image
--- 0.png
--- 1.png
(最后一部分摘自此问答。)
OpenCV 不能自己imwrite
生成文件夹,这必须明确地完成,参见。这个问答。
推荐阅读
- javascript - 从对象数组中删除原始和重复 - JS
- node.js - 我可以添加多个文档,尽管具有相同的值同时进行必要的验证(在模式中唯一设置为 true)
- javascript - 显示对象数组中的项目数,不重复
- javascript - 如何修复此错误:localhost/:1 加载资源失败:服务器响应状态为 404(未找到),无法获取 /
- robotics - 通过 Isaac 使用 Realsense 435i 的 NVIDIA Jetson Nano - 找不到相机
- python - Cmake 无法将“-fPIE”标志添加到 makefile
- python - 循环中定义的python lambda函数,最终指向相同的操作
- python - 为什么无论我使用什么 dtype 都会隐式地舍入一个数字?
- php - 无法解析来自 Soap 服务的 Curl 响应(发布请愿书)
- python - BeautifullSoup 返回整个 DIV,但没有值