python - 裁剪图像后转换 Numpy 数组
问题描述
我目前正在使用此代码:
def bundle_contour(image):
src_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
crop_img = cv2.resize(src_gray, (196, 196))
v = np.median(crop_img)
lower = int(max(0, (1.0 - 0.33) * v))
upper = int(min(255, (1.0 + 0.33) * v))
filter = cv2.bilateralFilter(src_gray, 9, 75, 75)
filter = filter.astype(np.uint8)
edged = cv2.Canny(filter, lower, upper)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
thresh = cv2.dilate(edged, kernel, iterations=2)
# Find contours in threshold image, then grab the largest one
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# Find the extreme points
extLeft = tuple(c[c[:, :, 0].argmin()][0])
extRight = tuple(c[c[:, :, 0].argmax()][0])
extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])
# crop new image out of the original image using the four extreme points (left, right, top, bottom)
new_image = image[extTop[1]:extBot[1], extLeft[0]:extRight[0]]
return new_image
def load_data(filename):
image = cv2.imread(filename)
# crop the bundle and ignore the unnecessary rest part of the image
cnt_image = bundle_contour(image)
# resize image
resized_image = cv2.resize(cnt_image, dsize=(196, 196), interpolation=cv2.INTER_CUBIC)
# normalize values
norm_image = resized_image / 255.
reshaped_img = norm_image.reshape(196,196,1)
return reshaped_img
def compose_dataset(df):
data = []
labels = []
for img_path, label in df.values:
data.append(load_data(img_path))
labels.append(label)
return np.array(data), np.array(labels)
X_train, y_train = compose_dataset(train_df)
print('Train data shape: {}, Labels shape: {}'.format(X_train.shape, y_train.shape))
我收到此错误:
ValueError:无法将大小为 115248 的数组重塑为形状 (196,196,1)。
如果我将代码更改为norm_image.reshape(196,196,-1)
,我的输出是:
Train data shape: (134, 196, 196, 3), Labels shape: (134,)
我怎样才能使输入到我的 CNN 的形状为 (196,196,1)?
解决方案
@HansHirse 完全正确。我正在写一个答案以使其更具体。
错误很可能是由load_data
方法引起的。由于您正在阅读图像但未转换为灰度。
因此,您需要添加句子
image = cv2.cvtColor(image, cv2.BGR2GRAY)
到load_data
. 所以正确的代码是:
def load_data(filename):
image = cv2.imread(filename)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# crop the bundle and ignore the unnecessary rest part of the image
cnt_image = bundle_contour(image)
# resize image
resized_image = cv2.resize(cnt_image, dsize=(196, 196), interpolation=cv2.INTER_CUBIC)
# normalize values
norm_image = resized_image / 255.
reshaped_img = norm_image.reshape(196,196,1)
return reshaped_img
如果您在bundle_contour
之后使用函数load_data
,则不需要这句话:
src_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
你可以删除它。
推荐阅读
- flutter - 在cmd上执行flutter build apk时构建失败
- php - 如何使用队列将数据传递到邮件视图?
- spring-boot - 谷歌日历域范围访问 401 日历
- vue.js - 特定条件下的类和样式绑定
- r - 恢复多次导入期间导入的文件数量
- django - Django forms.ModelMultipleChoiceField 没有保存任何东西
- wso2esb - WSO2 json 响应变量使用 xslt 转换
- python - 当我想使用“GridSearchCV”时出现权限错误
- mysql - Oracle 在 for 循环中提交
- security - 如何为您自己的应用程序创建一个 fail2ban 监狱和访问日志