Я разрабатываю приложение для Android для выполнения сегментации изображений с использованием Opencv в режиме реального времени.
Проблема в том, что при использовании детектора контуров Canny всегда присутствуют пропуски в обнаруженных контурах даже в условиях высокой яркости, но при включении вспышки смартфона обнаружение происходит точно.
И когда я включаю вспышку, также обнаруживаются тени, что не подходит для моих целей.
Я попытался увеличить значения пикселей с помощью метода Opencv convertTo
, и я попытался также увеличить камеру exposure
, но тщетно.
Вот мой код
Imgproc.cvtColor(orr, orr, Imgproc.COLOR_RGB2HSV);
Core.split(orr, channels);
orr = channels.get(1);
//orr.convertTo(orr, orr.type(), 1.1);
Core.meanStdDev(orr, mu, stddev);
CLAHE clahe = Imgproc.createCLAHE();
clahe.setClipLimit(1);
clahe.apply(orr, orr);
clahe.collectGarbage();
Imgproc.GaussianBlur(orr, orr, new Size(5, 5), 3);
Imgproc.Canny(orr, orr, mu.get(0, 0)[0], stddev.get(0, 0)[0], 3, false);
Imgproc.morphologyEx(orr, orr, Imgproc.MORPH_CLOSE, kernell);
Imgproc.dilate(orr, orr, Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(3, 3)));
Imgproc.findContours(orr, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
for (int i = contours.size() - 1; i >= 0; i--) {
double area = Imgproc.contourArea(contours.get(i), false); // Find the area of contour
if (area < min_area || contours.get(i).width() >= orr.width() / 3)
contours.remove(i);
}
if (contours.size() > 0) {
MatOfPoint2f approxCurve = new MatOfPoint2f();
rectList.clear();
for (int idx = 0; idx < contours.size(); idx++) {
//Convert contours(i) from MatOfPoint to MatOfPoint2f
MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(idx).toArray());
//Processing on mMOP2f1 which is in type MatOfPoint2f
double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;
Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);
//Convert back to MatOfPoint
MatOfPoint points = new MatOfPoint(approxCurve.toArray());
// Get bounding rect of contour
Rect rectt = Imgproc.boundingRect(points);
rectList.add(rect);
Mat miniature = new Mat(orr, new Rect(rectt.tl(), rectt.br()));
mats.add(miniature);
// draw enclosing rectangle (all same color, but you could use variable i to make them unique)
Imgproc.rectangle(rotated, rectt.tl(), rectt.br(), new Scalar(255, 0, 0));
}
}
Imgproc.resize(rotated, rotated, new Size(rotated.width() * 2, rotated.height() * 2));
long e2 = Core.getTickCount();
long e = e2 - e1;
double time = e / Core.getTickFrequency();
Вот изображение без вспышки
А вот и результат вывода со вспышкой
Итак, мой вопрос: что я могу сделать для точного обнаружения без использования вспышки телефона?