मैं प्रीप्रोसेसिंग और सेगमेंटेशन के लिए लाइब्रेरी Java
का उपयोग करते हुए OpenCV
, और Keras
मान्यता के लिए MNIST (0.98 की सटीकता के साथ) पर प्रशिक्षित मॉडल का उपयोग करते हुए, बहु-अंक मान्यता के साथ काम कर रहा हूं ।
मान्यता एक चीज के अलावा, काफी अच्छी तरह से काम करती है। नेटवर्क अक्सर लोगों को पहचानने में विफल रहता है (संख्या "एक")। यदि यह विभाजन के पूर्वप्रक्रमक / गलत कार्यान्वयन के कारण होता है, या यदि मानक MNIST पर प्रशिक्षित किसी नेटवर्क ने नंबर एक को नहीं देखा है जो मेरे परीक्षण मामलों जैसा दिखता है, तो मैं यह पता नहीं लगा सकता।
प्रीप्रोसेसिंग और विभाजन के बाद समस्याग्रस्त अंक क्या दिखते हैं:
बन जाता है और इसे वर्गीकृत किया जाता है 4
।
बन जाता है और इसे वर्गीकृत किया जाता है 7
।
बन जाता है और इसे वर्गीकृत किया जाता है 4
। और इसी तरह...
क्या यह कुछ ऐसा है जिसे विभाजन प्रक्रिया में सुधार करके तय किया जा सकता है? या प्रशिक्षण सेट को बढ़ाकर?
संपादित करें: प्रशिक्षण सेट (डेटा वृद्धि) को बढ़ाने से निश्चित रूप से मदद मिलेगी, जिसे मैं पहले से ही परीक्षण कर रहा हूं, सही प्रीप्रोसेसिंग का सवाल अभी भी बना हुआ है।
मेरी प्रीप्रोसेसिंग में आकार बदलना, ग्रेस्केल, बायनेरिज़ेशन, उलटा और फैलाव शामिल हैं। यहाँ कोड है:
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);
}