向图像添加填充以使它们成为相同的形状
Add padding to images to get them into the same shape
我有一个包含 100, 000 张不同大小图像的数据集。
(36,77), (56,100), (89,14), (35,67), (78,34), (90,65),(96,38).......
我想给这些图像添加填充,使它们成为相同的形状。
为此,我遍历整个数据集并采用 max_width 和 max_height 然后将图像制作成这个大小.
在此示例中,例如 max_height= 96
和 max_width= 100
。所以我的图像将具有 (96,100) 的所有形状。但是我得到不同的形状:
(96, 100, 3)
(97, 101, 3)
(97, 100, 3)
(96, 101, 3)
(96, 100, 3)
(97, 100, 3)
(97, 101, 3)
(97, 100, 3)
(97, 100, 3)
(96, 101, 3)
(97, 101, 3)
(96, 101, 3)
(96, 100, 3)
(97, 100, 3)
(96, 101, 3)
我的代码有什么问题
from __future__ import division
import cv2
import numpy as np
import csv
import os
import pandas as pd
import glob
from matplotlib import pyplot as plt
def max_width_height(path):
os.chdir(path)
WIDTH=[]
HEIGHT=[]
images_name = glob.glob("*.png")
set_img = set([x.rsplit('.', 1)[0] for x in images_name])
for img in set_img:
img_cv = cv2.imread(path+'/'+img+'.png')
h=img_cv.shape[0]
w=img_cv.shape[1]
WIDTH.append(w)
HEIGHT.append(h)
max_width=max(WIDTH)
max_height=max(HEIGHT)
return max_height,max_width
def add_padding(max_height,max_width):
path_char = '/cropped_images'
output = 'dataset/'
abby_label = []
reference = []
os.chdir(path_char)
img_char= glob.glob("*.png")
set_img_char = set([x.rsplit('.', 1)[0] for x in img_char])
images = []
size= []
for img in img_char:
img_cv = cv2.imread(path_char+'/'+img)
h,w=img_cv.shape[0:2]
width_diff=max_width-w
height_diff=max_height-h
left= width_diff/2
right=width_diff/2
top=height_diff/2
bottom=height_diff/2
if isinstance(left,float):
left=int(left)
right=left+1
if isinstance(top,float):
top=int(top)
bottom=top+1
white_pixels = [255, 255, 255]
black_pixels = [0, 0, 0]
constant = cv2.copyMakeBorder(img_cv,top,left,right,bottom, cv2.BORDER_CONSTANT, value=white_pixels)
cv2.imwrite(output+img,constant)
size.append(constant.shape)
constant2 = cv2.copyMakeBorder(img_cv,top,left,right,bottom, cv2.BORDER_CONSTANT, value=black_pixels)
cv2.imwrite(output+img,constant2)
label, sep,rest = img.partition('_')
abby_label.append(label)
reference.append(rest)
df = pd.DataFrame({'abby_label': abby_label, 'reference': reference})
df.to_csv('abby_labels.csv')
df2=pd.DataFrame({'dimension':size})
df2.to_csv('dimension.csv')
h,w=max_width_height(path)
print(h,w)
x=add_padding(h,w)
问题出在这里:
left= width_diff/2
right=width_diff/2
top=height_diff/2
bottom=height_diff/2
这将导致不同的最终宽度或高度,具体取决于 width_diff 或 height_diff 是否可以被 2 整除。您已实施解决方法,但这仅适用于 Python 3 当你显然在使用 Python 2.
您可以通过以下方式解决此问题:
left=width_diff/2
right=width_diff - left
top=height_diff/2
bottom=height_diff - top
通过这种方式,您将确保
- 左 + 右 = width_diff
- 顶部 + 底部 = height_diff
请注意,这特别适用于 Python 2,您可能有兴趣阅读 Python integer division yields float. My suggestion is to use floor division,这样您的代码就不会受到 Python 2 和 Python 3个差异。
left=width_diff//2
right=width_diff - left
top=height_diff//2
bottom=height_diff - top
对于像素数为 odd/even 的图像来说,这似乎是一个舍入误差。
如果width_diff
是偶数,可以边做边除以2。但如果是奇数,则需要在一侧添加 width_diff//2
,在另一侧添加 (width_diff//2) + 1
。这同样适用于高度。
或者只是 运行 处于调试模式的程序(因为您有要分析的图像)并确保 odd/even 尺寸的图像按照您期望的方式处理。
我有一个包含 100, 000 张不同大小图像的数据集。
(36,77), (56,100), (89,14), (35,67), (78,34), (90,65),(96,38).......
我想给这些图像添加填充,使它们成为相同的形状。
为此,我遍历整个数据集并采用 max_width 和 max_height 然后将图像制作成这个大小.
在此示例中,例如 max_height= 96
和 max_width= 100
。所以我的图像将具有 (96,100) 的所有形状。但是我得到不同的形状:
(96, 100, 3)
(97, 101, 3)
(97, 100, 3)
(96, 101, 3)
(96, 100, 3)
(97, 100, 3)
(97, 101, 3)
(97, 100, 3)
(97, 100, 3)
(96, 101, 3)
(97, 101, 3)
(96, 101, 3)
(96, 100, 3)
(97, 100, 3)
(96, 101, 3)
我的代码有什么问题
from __future__ import division
import cv2
import numpy as np
import csv
import os
import pandas as pd
import glob
from matplotlib import pyplot as plt
def max_width_height(path):
os.chdir(path)
WIDTH=[]
HEIGHT=[]
images_name = glob.glob("*.png")
set_img = set([x.rsplit('.', 1)[0] for x in images_name])
for img in set_img:
img_cv = cv2.imread(path+'/'+img+'.png')
h=img_cv.shape[0]
w=img_cv.shape[1]
WIDTH.append(w)
HEIGHT.append(h)
max_width=max(WIDTH)
max_height=max(HEIGHT)
return max_height,max_width
def add_padding(max_height,max_width):
path_char = '/cropped_images'
output = 'dataset/'
abby_label = []
reference = []
os.chdir(path_char)
img_char= glob.glob("*.png")
set_img_char = set([x.rsplit('.', 1)[0] for x in img_char])
images = []
size= []
for img in img_char:
img_cv = cv2.imread(path_char+'/'+img)
h,w=img_cv.shape[0:2]
width_diff=max_width-w
height_diff=max_height-h
left= width_diff/2
right=width_diff/2
top=height_diff/2
bottom=height_diff/2
if isinstance(left,float):
left=int(left)
right=left+1
if isinstance(top,float):
top=int(top)
bottom=top+1
white_pixels = [255, 255, 255]
black_pixels = [0, 0, 0]
constant = cv2.copyMakeBorder(img_cv,top,left,right,bottom, cv2.BORDER_CONSTANT, value=white_pixels)
cv2.imwrite(output+img,constant)
size.append(constant.shape)
constant2 = cv2.copyMakeBorder(img_cv,top,left,right,bottom, cv2.BORDER_CONSTANT, value=black_pixels)
cv2.imwrite(output+img,constant2)
label, sep,rest = img.partition('_')
abby_label.append(label)
reference.append(rest)
df = pd.DataFrame({'abby_label': abby_label, 'reference': reference})
df.to_csv('abby_labels.csv')
df2=pd.DataFrame({'dimension':size})
df2.to_csv('dimension.csv')
h,w=max_width_height(path)
print(h,w)
x=add_padding(h,w)
问题出在这里:
left= width_diff/2
right=width_diff/2
top=height_diff/2
bottom=height_diff/2
这将导致不同的最终宽度或高度,具体取决于 width_diff 或 height_diff 是否可以被 2 整除。您已实施解决方法,但这仅适用于 Python 3 当你显然在使用 Python 2.
您可以通过以下方式解决此问题:
left=width_diff/2
right=width_diff - left
top=height_diff/2
bottom=height_diff - top
通过这种方式,您将确保
- 左 + 右 = width_diff
- 顶部 + 底部 = height_diff
请注意,这特别适用于 Python 2,您可能有兴趣阅读 Python integer division yields float. My suggestion is to use floor division,这样您的代码就不会受到 Python 2 和 Python 3个差异。
left=width_diff//2
right=width_diff - left
top=height_diff//2
bottom=height_diff - top
对于像素数为 odd/even 的图像来说,这似乎是一个舍入误差。
如果width_diff
是偶数,可以边做边除以2。但如果是奇数,则需要在一侧添加 width_diff//2
,在另一侧添加 (width_diff//2) + 1
。这同样适用于高度。
或者只是 运行 处于调试模式的程序(因为您有要分析的图像)并确保 odd/even 尺寸的图像按照您期望的方式处理。