【发布时间】:2020-02-12 09:20:21
【问题描述】:
我正在使用 Java 进行手印多位识别,使用 OpenCV 库进行预处理和分割,并使用在 MNIST 上训练的 Keras 模型(精度为 0.98)进行识别。
除了一件事之外,识别似乎工作得很好。网络经常无法识别那些(数字“一”)。我不知道它是否是由于预处理/不正确的分割实现而发生的,或者如果在标准 MNIST 上训练的网络只是没有看到看起来像我的测试用例的第一。
这是有问题的数字在预处理和分割后的样子:
这是否可以通过改进分割过程来解决?还是通过增强训练集?
编辑:增强训练集(数据增强)肯定会有所帮助,我已经在测试,但正确预处理的问题仍然存在。
我的预处理包括调整大小、转换为灰度、二值化、反转和膨胀。代码如下:
Mat resized = new Mat();
Imgproc.resize(image, resized, new Size(), 8, 8, Imgproc.INTER_CUBIC);
Mat grayscale = new Mat();
Imgproc.cvtColor(resized, grayscale, Imgproc.COLOR_BGR2GRAY);
Mat binImg = new Mat(grayscale.size(), CvType.CV_8U);
Imgproc.threshold(grayscale, binImg, 0, 255, Imgproc.THRESH_OTSU);
Mat inverted = new Mat();
Core.bitwise_not(binImg, inverted);
Mat dilated = new Mat(inverted.size(), CvType.CV_8U);
int dilation_size = 5;
Mat kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_CROSS, new Size(dilation_size, dilation_size));
Imgproc.dilate(inverted, dilated, kernel, new Point(-1,-1), 1);
然后将预处理后的图像分割成单独的数字,如下所示:
List<Mat> digits = new ArrayList<>();
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(preprocessed.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// code to sort contours
// code to check that contour is a valid char
List rects = new ArrayList<>();
for (MatOfPoint contour : contours) {
Rect boundingBox = Imgproc.boundingRect(contour);
Rect rectCrop = new Rect(boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height);
rects.add(rectCrop);
}
for (int i = 0; i < rects.size(); i++) {
Rect x = (Rect) rects.get(i);
Mat digit = new Mat(preprocessed, x);
int border = 50;
Mat result = digit.clone();
Core.copyMakeBorder(result, result, border, border, border, border, Core.BORDER_CONSTANT, new Scalar(0, 0, 0));
Imgproc.resize(result, result, new Size(28, 28));
digits.add(result);
}
【问题讨论】:
-
你使用蒙版或(蒙版?)原始灰度像素作为分类的输入?
-
@Micka 我正在使用预处理(二值化、倒置、扩张)版本。与 MNIST 训练集匹配的那些。我的帖子中有预处理后数字“1”的例子。
标签: java opencv machine-learning image-recognition mnist