Мне нужно идентифицировать относительно маленький объект (глиняного голубя) на больших (1080p) изображениях. Фон разнообразен, между зданиями, деревьями, небом, чем угодно.
Я использую OpenCV и потратил немало недель, изучая его, и добился определенных успехов, используя комбинацию inRange, Canny, Blur, ОДНАКО, это зависит от идентификации глиняного голубя только по цвету:
public List<MatOfPoint> FindContours(Mat drawing, Scalar lowerBound, Scalar upperBound)
{
Mat scratch = new Mat();
Mat res = new Mat();
Imgproc.blur(drawing, scratch, new Size(blur, blur));
cvtColor(scratch, scratch, COLOR_BGR2HSV);
Core.inRange(scratch, lowerBound, upperBound, scratch);
Imgproc.Canny(scratch, res, threshold, threshold * 2, kernel_size);
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(res, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
return contours;
}
cal.lowerBoundTarget = new Scalar(0,84,19);
cal.upperBoundTarget = new Scalar(343,100,100);
List<MatOfPoint> contours = FindContours(src, cal.lowerBoundTarget, cal.upperBoundTarget);
Исходное изображение - случайное изображение глиняного голубя в полете.
Алгоритм достаточно хорошо работает на простых изображениях, подобных этим:
https://imgur.com/1p1sI7H
https://imgur.com/edX1li7
Но с разными условиями освещения и фоном он не может определить глину:
https://imgur.com/iRV8JQw
https://imgur.com/ZqYDh1a
Я обнаружил, что значения HSV для глины сильно варьируются, что затрудняет его идентификацию, на самом деле диапазон, который я заключил, охватывает очень широкий диапазон. Что не очень помогает.
Любые идеи о наборе шагов, которые позволят надежно идентифицировать глины, не имеют значения фону (в пределах разумного - то есть фоны, цвета которых эффективно делают глину невидимой, можно игнорировать).