如何在scikit-learn中分类具有各种大小和格式的不同图像? [英] How can I classify different images with various sizes and formats in scikit-learn?

查看:116
本文介绍了如何在scikit-learn中分类具有各种大小和格式的不同图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用scikit-learn构建一个简单的图像分类器.我希望避免在训练之前必须调整大小和转换每个图像.

I'm trying to build a simple image classifier using scikit-learn. I'm hoping to avoid having to resize and convert each image before training.

给出两个具有不同格式和大小(1.jpg2.png)的不同图像,如何在拟合模型时避免使用ValueError?

Given two different images that are different formats and sizes (1.jpg and 2.png), how can I avoid a ValueError while fitting the model?

  • 我有一个例子,我仅使用1.jpg进行训练,非常适合.
  • 还有另一个示例,其中我同时使用1.jpg2.png进行训练,并且生成了ValueError.
  • I have one example where I train using only 1.jpg, which fits successfully.
  • I have another example where I train using both 1.jpg and 2.png and a ValueError is produced.
import numpy as np
from sklearn import svm 
import matplotlib.image as mpimg

target = [1, 2]
images = np.array([
    # target 1
    [mpimg.imread('./1.jpg'), mpimg.imread('./1.jpg')],
    # target 2
    [mpimg.imread('./1.jpg'), mpimg.imread('./1.jpg')],
])
n_samples = len(images)
data = images.reshape((n_samples, -1))
model = svm.SVC()
model.fit(data, target)

此示例将引发Value错误.

观察目标2中的其他2.png图像.

This example will raise a Value error.

Observe the different 2.png image in target 2.

import numpy as np
from sklearn import svm 
import matplotlib.image as mpimg

target = [1, 2]
images = np.array([
    # target 1
    [mpimg.imread('./1.jpg'), mpimg.imread('./1.jpg')],
    # target 2
    [mpimg.imread('./2.png'), mpimg.imread('./1.jpg')],
])
n_samples = len(images)
data = images.reshape((n_samples, -1))
model = svm.SVC()
model.fit(data, target)
# ValueError: setting an array element with a sequence.

1.jpg

推荐答案

为此,我真的建议使用Keras中的工具,这些工具专门用于以高度可扩展和高效的方式预处理图像.

For this, I would really recommend using the tools in Keras that are specifically designed to preprocess images in a highly scalable and efficient way.

from keras.preprocessing.image import ImageDataGenerator
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

1确定新图片的目标尺寸

h,w = 150,150 # desired height and width
batch_size = 32 
N_images = 100 #total number of images

Keras是批量工作的,因此batch_size只是确定一次要处理多少张图片(这不会影响最终结果,只会影响速度).

Keras works in batches, so batch_size just determines how many pictures at once will be processed (this does not impact your end result, just the speed).

train_datagen = ImageDataGenerator(
    rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    'Pictures_dir',
    target_size=(h, w),
    batch_size=batch_size,
    class_mode = 'binary')

将要进行图像提取的对象是ImageDataGenerator.它具有方法flow_from_directory,我相信这里可能对您有用.它将读取文件夹Pictures_dir的内容,并希望您的图像按类位于文件夹中(例如:Pictures_dir/class0和Pictures_dir/class1).生成器在被调用时将随后从这些文件夹中创建图像并导入其标签(在此示例中为"class0"和"class1").

The object that is going to do the image extraction is ImageDataGenerator. It has the method flow_from_directory which I believe might be useful for you here. It will read the content of the folder Pictures_dir and expect your images to be in folders by class (eg: Pictures_dir/class0 and Pictures_dir/class1). The generator, when called, will then create images from these folders and also import their label (in this example, 'class0' and 'class1').

此生成器还有很多其他参数,您可以在Keras文档中进行检查(特别是如果您想进行数据扩充).

There are plenty of other arguments to this generator, you can check them out in the Keras documentation (especially if you want to do data augmentation).

注意:这将按照您的要求拍摄任何图像,无论是PNG还是JPG

Note: this will take any image, be it PNG or JPG, as you requested

如果要获取从类名到标签索引的映射,请执行以下操作:

If you want to get the mapping from class names to label indices, do:

train_generator.class_indices
# {'class0': 0, 'class1': 1}

您可以检查

plt.imshow(train_generator[0][0][0])

3从生成器中提取所有调整大小的图像

现在您可以从ImageGenerator中提取图像了:

3 Extract all resized images from the Generator

Now you are ready to extract the images from the ImageGenerator:

def extract_images(generator, sample_count):
    images = np.zeros(shape=(sample_count, h, w, 3))
    labels = np.zeros(shape=(sample_count))
    i = 0
    for images_batch, labels_batch in generator: # we are looping over batches
        images[i*batch_size : (i+1)*batch_size] = images_batch
        labels[i*batch_size : (i+1)*batch_size] = labels_batch
        i += 1
        if i*batch_size >= sample_count:
            # we must break after every image has been seen once, because generators yield indifinitely in a loop
            break
    return images, labels

images, labels = extract_images(train_generator, N_images)

print(labels[0])
plt.imshow(images[0])

现在,在images中所有图像的大小均相同,在labels中具有相应的标签,然后您可以将其输入到您选择的任何scikit-learn分类器中.

Now you have your images all at the same size in images, and their corresponding labels in labels, which you can then feed into any scikit-learn classifier of your choice.

这篇关于如何在scikit-learn中分类具有各种大小和格式的不同图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆