OpenCV скорость обнаружения дорожных знаков

У меня проблема с обнаружением знаков дорожного движения в opencv 2.4 для Android. Я делаю следующее:

"захват кадра -> преобразовать его в HSV -> извлечь красные области -> обнаружить знаки с помощью обнаружения эллипса"

До сих пор обнаружение эллипса работает идеально, если изображение хорошего качества. Но, как вы видите на рисунках ниже, это красное извлечение не работает нормально, по моему мнению, из-за низкого качества кадров.

Преобразование исходного изображения в HSV:

Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3);

Извлечение красного цвета:

Core.inRange(this.source, new Scalar(this.h,this.s,this.v), new Scalar(230,180,180), this.source);

Поэтому у меня вопрос: есть ли другой способ обнаружения дорожного знака, подобного этому, или выделения из него красных областей, который, кстати, может быть очень слабым, как на последней картинке?

Это оригинальное изображение:

Это преобразуется в HSV, так как красные области выглядят так же, как и близлежащие деревья. Вот как я должен знать, что он красный, но не могу.

Преобразовано в HSV:

Это с извлеченными красными цветами. Если цвета будут правильными, я получу почти идеальный круг / эллипс вокруг знака, но он не является полным из-за ложных цветов.

Результат после извлечения:

Метод эллипса:

private void findEllipses(Mat input){
Mat thresholdOutput = new Mat();
int thresh = 150;

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();

Imgproc.threshold(source, thresholdOutput, thresh, 255, Imgproc.THRESH_BINARY);
//Imgproc.Canny(source, thresholdOutput, 50, 180);
Imgproc.findContours(source, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
RotatedRect minEllipse[] = new RotatedRect[contours.size()];

for(int i=0; i<contours.size();i++){
    MatOfPoint2f temp=new MatOfPoint2f(contours.get(i).toArray());

    if(temp.size().height > minEllipseSize && temp.size().height < maxEllipseSize){
        double a = Imgproc.fitEllipse(temp).size.height;
        double b = Imgproc.fitEllipse(temp).size.width;
        if(Math.abs(a - b) < 10)
            minEllipse[i] = Imgproc.fitEllipse(temp);
    }
}
detectedObjects.clear();
for( int i = 0; i< contours.size(); i++ ){
    Scalar color = new Scalar(180, 255, 180);
    if(minEllipse[i] != null){
        detectedObjects.add(new DetectedObject(minEllipse[i].center));
        DetectedObject detectedObj = new DetectedObject(minEllipse[i].center);
        Core.ellipse(source, minEllipse[i], color, 2, 8);
    }
}

}

Проблемный признак:

Ответы на вопрос(4)

Ваш ответ на вопрос