Search
Write a publication
Pull to refresh

Comments 9

Результаты сегментации запрещающих (красных) знаков будут лучше, если в HSV добавить дополнительно участок значений цветового тона от, скажем, 340 до 360.

Возможно это и будет работать, но есть вероятность появление шума и выделения не только знаков, но и не нужных объектов. Степень ошибок сегментации будет варьироваться в зависимости от яркости изображения и других факторов.

P.S.: В данном случае подбиралось значение HSV для представленных изображений, что позволило получить более менее нормальный результат.

Каких ненужных объектов? У вас знаки - красные, других ярких красных объектов нет. Понимаете, красные оттенки имеют разрыв в HSB из-за цикличности компоненты цветового тона H -от 0 до 360 градусов. Оттенки с H=359 и H=1 - весьма близкие.

А где-то можно подробнее почитать про IHSL, кроме вашей собственной статьи издательства рязанского госуниверситета, которая не гуглится?

А. Там авторы используют наименование IHLS, а я искал IHSL, как написано в данной статье, и не находил.

Прикреплю код на C, который использовался для преобразования RGB в IHSL.

uint32_t ZETTA;
uint32_t GAMMA;

typedef enum
{
    cn_grayscale = 1,
    cn_rgb = 3

} channel;

typedef struct image_mat_structure
{
    unsigned char *data;
    unsigned int width;
    unsigned int height;
    channel cn;

} *image_mat;



void rgb_to_ihsl_mask(const image_mat image_src, image_mat image_dst)
{
    uint32_t size_mat = image_src->height * image_src->width;

    // Объявление переменных
    uint8_t H, S, L;
    uint8_t R, G, B;
    
    // Угол в цветовом пространстве HSL;
    double theta;
    double denominator;
    double argument;


    // Максимально и минимальное значение пикселей в каналах
    uint8_t max, min;


    for (uint32_t i = 0; i < size_mat; i++)
    {

        R = (image_src->data)[i * 3];
        G = (image_src->data)[i * 3 + 1];
        B = (image_src->data)[i * 3 + 2];

        denominator = sqrt((double)R*R + (double)G*G + (double)B*B - (double)R*G - (double)R*B - (double)G*B);
        argument = ((double)R - (double)G / 2.0 - (double)B / 2.0) / denominator;

        if (argument < -1.0) argument = -1.0;
        if (argument > 1.0) argument = 1.0;

        // Нахождение угла
        theta = acos(argument);
   
        // Находждение Hue
        if (B <= G)
        {
            H = (uint8_t) theta * (180.0 / M_PI_MY);
        }
        else 
        {
            H = (uint8_t) (360 - theta * (180.0 / M_PI_MY));
        }

        if (argument < -1.0) argument = -1.0;
        if (argument > 1.0) argument = 1.0;
     
        // Нахождение максимального значения пикселя из 3-х каналов
        max = (R > G ? (R > B ? R : B) : (G > B ? G : B));
        min = (R < G ? (R < B ? R : B) : (G < B ? G : B));

        // Нахождение Saturation
        S = max - min;

        // Нахождение Luminance
        L = (uint8_t)(0.212 * R + 0.715 * G + 0.072 * B);

        if (max == G || ((abs(R - G) < ZETTA) && (abs(B - G) < GAMMA)))
        {
            // (image_dst->data)[i * 3] = 0;
            // (image_dst->data)[i * 3 + 1] = 0;
            // (image_dst->data)[i * 3 + 2] = 0;
            (image_dst->data)[i] = 0;
        }       
        else
        {
            if ((61 <= H && H <= 150 && S >= 20 && L >= 0) ||   // Зеленые
                (150 <= H && H <= 250 && S >= 20 && L >= 10) || // Синие
                (30 <= H && H <= 60 && S >= 90 && S <= 255 && L >= 80)) // Желтые
        
            { 
                //Сохраняем значения в HSL
                // (image_dst->data)[i * 3] = H;
                // (image_dst->data)[i * 3 + 1]  = S;
                // (image_dst->data)[i * 3 + 2]  = L;
                (image_dst->data)[i] = 255;
            }
            // Сохраняем значения в RGB
            // (image_dst->data)[i] = 255;
        }
    }    
}

"Дорожникам" давно пора держать актуальными открытые карты дорожной ситуации/обстановки/режимов.

Sign up to leave a comment.

Articles