Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
2 / 2 / 0
Регистрация: 14.10.2018
Сообщений: 122

Ошибка при переводе из RGB в HSL

18.11.2021, 16:00. Показов 2103. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Пытаюсь исправлять код, но выводит вот такую ошибку: System.ArgumentException: "Значение '300' недопустимо для 'red'. 'red' должно быть больше или равно 0 и меньше или равно 255.". Собственно понимаю, что H[0;360], а R[0;255], вот только не знаю как исправить такое.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  private void HLS_Click(object sender, EventArgs e)
        {
            int i, j;
            var image = new Bitmap(firstimage.Image);
            Bitmap[] result = new Bitmap[] { new Bitmap(image.Width, image.Height), new Bitmap(image.Width, image.Height), new Bitmap(image.Width, image.Height) };
            int width = image.Width;
            int height = image.Height;
            byte[,] image_matr;
            image_matr = new byte[width,height];
            for (i = 0; i < width; i++)
            {
                for (j = 0; j < height; j++)
                {
                  
                    Color color = image.GetPixel(i, j);
                    int R = Convert.ToInt32(color.R)/255;
                    int G = Convert.ToInt32(color.G) / 255;
                    int B = Convert.ToInt32(color.B) / 255;
                    double max = Math.Max(R, Math.Max(G, B));
                    double min = Math.Min(R, Math.Min(G, B));
                    double h=0, s=0, l;
                    if (image_matr[i, j] > 255)
                        image_matr[i, j] = 255;
                    if (image_matr[i, j] < 0)
                        image_matr[i, j] = 0;
                    l = (max + min) / 2.0;
 
                    if (max==min)
                    { h = 0; //undefined
                    }
                    else if(max==R && G>=B)
                    { h = 60.0 * (G - B) / (max - min); }
                    else if (max == R && G < B)
                    { h = 60.0 * (G - B) / (max - min) + 360.0; }
                    else if (max == G)
                    { h = 60.0 * (B - R) / (max - min) + 120.0; }
                    else if (max == B)
                    { h = 60.0 * (R - G) / (max - min) + 240.0; }
 
                    if (l == 0 || max == min)
                    { s = 0; }
                    else if (l>0 && l <= 0.5)
                    { s = (max - min) / (max + min); }
                    else if (l<1 && l>0.5)
                    { s = (max - min) / (2 - (max + min)); }
                    h = Math.Round(h);
                    s = Math.Round(s);
                    l = Math.Round(l);
                    int H = Convert.ToInt32(h);
                    int S = Convert.ToInt32(s);
                    int L= Convert.ToInt32(l);
                    result[0].SetPixel(i, j, Color.FromArgb(color.A, H, 0, 0));
                    result[1].SetPixel(i, j, Color.FromArgb(color.A, 0, S, 0));
                    result[2].SetPixel(i, j, Color.FromArgb(color.A, 0, 0, L));
                }
            }
            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox1.Image = result[0];
            pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox2.Image = result[1];
            pictureBox3.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox3.Image = result[2];
 
        }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.11.2021, 16:00
Ответы с готовыми решениями:

Ошибка в переводе LAB в RGB
Здравствуйте, уважаемые форумчане! Перевожу RGB изображение в LAB и обратно: rgbI = imread('krasniy_dom_sum_750.tif'); LAB =...

convert rgb to hsl
привет всем!! а как называется функция которая переводит RGB в HSL ? желательно с примером...и посоветуйте книгу на эту тему...

Перевести картинку из цветовой модели HSL в RGB
Может быть у кого того есть проект, где нужно превратить картинку из цветовой модели HSL в RGB , C# Windows Form?

7
 Аватар для roach1967
983 / 463 / 233
Регистрация: 27.06.2014
Сообщений: 1,033
21.11.2021, 18:26
Лучший ответ Сообщение было отмечено Invisibletime как решение

Решение

Во первых - измените строки 16-18 на
C#
1
2
3
double R = color.R / 255.0;
double G = color.G / 255.0;
double B = color.B / 255.0;
Во вторых измените строки 49-51, что-бы привести H[0;360], S[0;1] и L[0;1] к диапазону [0;255]:
C#
1
2
3
h = Math.Round(h / 1.412);
s = Math.Round(s * 255);
l = Math.Round(l * 255);
1
2 / 2 / 0
Регистрация: 14.10.2018
Сообщений: 122
22.11.2021, 11:20  [ТС]
Большое вам спасибо. Но вот должен ли быть такой результат ?
Миниатюры
Ошибка при переводе из RGB в HSL  
0
 Аватар для roach1967
983 / 463 / 233
Регистрация: 27.06.2014
Сообщений: 1,033
22.11.2021, 11:22
Да. Такие картинки и получаются...
1
2 / 2 / 0
Регистрация: 14.10.2018
Сообщений: 122
22.11.2021, 11:36  [ТС]
Понял. Огромное вам спасибо
0
2 / 2 / 0
Регистрация: 14.10.2018
Сообщений: 122
24.11.2021, 18:09  [ТС]
Добрый вечер, прошу прощения, что опять пишу, хотя тема закрыта. Просто оказалось, что все таки картинки не должны выводится в таком виде, так как они выводят словно RGB, но с изменениями. В общем получается, что мне повторно нужно еще переводить из HSL в RGB (это сделал), после этого просто не пойму как вывести эти новые значения T в массив result. Пока что на экран выводятся только черные изображения.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 private void hls_Click(object sender, EventArgs e)
        {
            if (firstimage.Image == null)
            {
                MessageBox.Show("Сначала загрузите изображение");
                return;
            }
            Bitmap[] img = RgbToHls((Bitmap)firstimage.Image);
            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox1.Image = img[0];
            pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox2.Image = img[1];
            pictureBox3.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox3.Image = img[2];
            Bitmap first = new Bitmap(pictureBox1.Image);
            Bitmap second = new Bitmap(pictureBox2.Image);
            Bitmap third = new Bitmap(pictureBox3.Image);
 
        }
        static Bitmap[] RgbToHls(Bitmap source)
        { 
        int i, j;
           // var image = new Bitmap(firstimage.Image);
            Bitmap[] result = new Bitmap[] { new Bitmap(source.Width, source.Height), new Bitmap(source.Width, source.Height), new Bitmap(source.Width, source.Height) };
            int width = source.Width;
            int height = source.Height;
            byte[,] image_matr;
            double Q=0,P=0;
            double[] T = new double[3];
            image_matr = new byte[width,height];
            for (i = 0; i < width; i++)
            {
                for (j = 0; j < height; j++)
                {
                  
                    Color color = source.GetPixel(i, j);
                    double R = color.R / 255.0;
                    double G = color.G / 255.0;
                    double B = color.B / 255.0;
                    
                    double max = Math.Max(R, Math.Max(G, B));
                    double min = Math.Min(R, Math.Min(G, B));
                    double del = max-min;
                    double h=0, s=0, l;
                    if (image_matr[i, j] > 255)
                        image_matr[i, j] = 255;
                    if (image_matr[i, j] < 0)
                        image_matr[i, j] = 0;
                    l = (max + min) / 2.0;
 
                    if (del==0)
                    { h = 0; //undefined
                    }
                    else if(max==R && G>=B)
                    { h = Math.Abs( 60.0 * (G - B) / (max - min)); }
                    else if (max == R && G < B)
                    { h = Math.Abs(60.0 * (G - B) / (max - min) + 360.0); }
                    else if (max == G)
                    { h = Math.Abs(60.0 * (B - R) / (max - min) + 120.0); }
                    else if (max == B)
                    { h = Math.Abs(60.0 * (R - G) / (max - min) + 240.0); }
 
                    if (l == 0 || max == min)
                    { s = 0; }
                    else if (l>0 && l <= 0.5)
                    { s = Math.Abs((max - min) / (max + min)); }
                    else if (l<1 && l>0.5)
                    { s = Math.Abs((max - min) / (2 - (max + min))); }
                    // if (h < 0)
                    //    h =h+360;
                    // h = Math.Round(h*0.7083332);
                    h = Math.Round(h);
                    s = Math.Round(s);
                    l = Math.Round(l);
                    int H = Convert.ToInt32(h);
                    int S = Convert.ToInt32(s);
                    int L= Convert.ToInt32(l);
                    // double hue = color.GetHue();
                    // double sat = color.GetSaturation();
                    // double light = color.GetBrightness();
                    // int H1 = (Int32)hue;
                    // int S2 = (Int32)sat;
                    // int L1 = (Int32)light;
                    // перевод обратно в rgb по формуле , затем в массив передавать новые переменные. 
                    //для зашумления тоже после добавления шума нужно будет обратно перевести в rgb 
                    if (l < 0.5)
                        Q = l * (1.0 + s);
                    else if (l >= 0.5)
                        P = 2.0 * l - Q;
                    double hk = h / 360;
                    T[0] = hk + (1 / 3);//Tr
                    T[1] = hk;//Tg
                    T[2] = hk - (1 / 3);//Tb
                   
                    for(int i1=0;i1<3;i1++)
                    {
                        if (T[i1] < 0)
                            T[i1] += 1;
                        else if(T[i1]>1)
                            T[i1] -= 1;
                        if (T[i1] < (1 / 6))
                            T[i1] = P + ((Q - P) * 6 * T[i1]);
                        else if (T[i1] < (1/ 2) && T[i1] >= (1 / 6))
                            T[i1] = Q;
                        else if (T[i1] < (2/3) && T[i1] >= (1 /2))
                            T[i1] = P + ((Q - P) * ((2 / 3) - T[i1]) * 6);
                        else
                            T[i1] = P;
                        T[0] = Math.Round(T[0]);
                        T[1] = Math.Round(T[1]);
                        T[2] = Math.Round(T[2]);
                        int H1 = Convert.ToInt32(T[0]);
                        int S1 = Convert.ToInt32(T[1]);
                        int L1 = Convert.ToInt32(T[2]);
                    result[0].SetPixel(i, j, Color.FromArgb(color.A, H1 , 0, 0));
                    result[1].SetPixel(i, j, Color.FromArgb(color.A, 0, S1, 0));
                    result[2].SetPixel(i, j, Color.FromArgb(color.A, 0, 0, L1));
                    } 
                }
            } return result;
        }
0
964 / 485 / 241
Регистрация: 02.06.2016
Сообщений: 760
25.11.2021, 04:35
Лучший ответ Сообщение было отмечено Invisibletime как решение

Решение

Invisibletime, во-первых, вот эти вот штуки: (2/3) дают ноль в результате, т.к. происходит целочисленное деление. Во-вторых, Вам необходимо разнести код по отдельным функциям, т.к. по задумке конвертацию нужно делать минимум три раза.
Цитата Сообщение от Invisibletime Посмотреть сообщение
Пока что на экран выводятся только черные изображения
Это в-третьих. Да, чтобы разложить по базису нужно занулить компоненты вектора (h,s,l)=(h,0,0)+(0,s,0)+(0,0,l), но с точки зрения изображения мы, получается, выкручиваем в ноль, например, яркость, и картинка становится черной. Вот, смотрите:
  • (h, 0, 0) - здесь яркость нулевая, картинка черная и канала H не видно.
  • (h, 0, 1) - здесь яркость 1, картинка белая и канала H не видно.
  • (h, 0, 0.5) - здесь яркость 0.5, но канала H не видно, потому что сатурация выкручена в ноль, а она отвечает за то сколько цветовой соствляющей (т.е. параметра H) попадет на экран.
  • (h, 0.5, 0.5) - вот так можно увидеть канал H на нейтральном сером фоне.
  • (0,s,0) - тут тоже яркость на нуле.
  • (0,s,0.5) - здесь все хорошо, но нулевой канал H дает нам красный оттенок, что может мешать восприятию. Для того, чтобы увидеть(!) канал S нужно использовать среднее значение яркости(L) и любое значение тона (H).
Исправленный вариант
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
Bitmap[] RgbToHls(Bitmap source)
{
    int width = source.Width;
    int height = source.Height;
 
    var result = new[] {
        new Bitmap(width, height),
        new Bitmap(width, height),
        new Bitmap(width, height)};
 
    for (var i = 0; i < width; i++)
    {
        for (var j = 0; j < height; j++)
        {
            var rgb = source.GetPixel(i, j);
            var (h, s, l) = RGB_to_HSL(rgb);
 
            //h = rgb.GetHue();
            //s = rgb.GetSaturation();
            //l = rgb.GetBrightness();
 
            result[0].SetPixel(i, j, HSL_to_RGB(h, 1, 0.5));
            result[1].SetPixel(i, j, HSL_to_RGB(0, s, 0.5));
            result[2].SetPixel(i, j, HSL_to_RGB(0, 0, l));
 
            // вариант с серым цветом по каналам hsl
            //result[0].SetPixel(i, j, Gray(h / 360));
            //result[1].SetPixel(i, j, Gray(s));
            //result[2].SetPixel(i, j, Gray(l));
 
            // для проверки формул перевода
            // конвертируем rgb -> hsl -> rgb
            // должна получиться исходная картинка
            // result[0].SetPixel(i, j, HSL_to_RGB(h, s, l));
        }
    }
 
    return result;
}
 
// из числа между 0 и 1 делает серый цвет
Color Gray(double x)
{
    var g = Math.Max(0, Math.Min(255, (int)(255 * x)));
    return Color.FromArgb(g, g, g);
}
 
(double H, double S, double V) RGB_to_HSL(Color rgb)
{
    double R = rgb.R / 255.0;
    double G = rgb.G / 255.0;
    double B = rgb.B / 255.0;
    double max = Math.Max(R, Math.Max(G, B));
    double min = Math.Min(R, Math.Min(G, B));
    double H = 0, S = 0;
    double L = (max + min) / 2.0;
 
    if (max == min)
    {
        H = 0; //undefined
    }
    else if (max == R && G >= B)
    { H = 60.0 * (G - B) / (max - min); }
    else if (max == R && G < B)
    { H = 60.0 * (G - B) / (max - min) + 360.0; }
    else if (max == G)
    { H = 60.0 * (B - R) / (max - min) + 120.0; }
    else if (max == B)
    { H = 60.0 * (R - G) / (max - min) + 240.0; }
 
    if (L == 0 || max == min)
    { S = 0; }
    else if (L > 0 && L <= 0.5)
    { S = (max - min) / (max + min); }
    else if (L < 1 && L > 0.5)
    { S = (max - min) / (2 - (max + min)); }
 
    return (H, S, L);
}
 
Color HSL_to_RGB(double H, double S, double L)
{
    double Q = L < 0.5 ? L * (1.0 + S) : L + S - L * S;
    double P = 2.0 * L - Q;
    double Hk = H / 360;
    double[] T = new double[3];
    int[] C = new int[3];
 
    T[0] = Hk + (1.0 / 3.0);//Tr
    T[1] = Hk;              //Tg
    T[2] = Hk - (1.0 / 3.0);//Tb
 
    for (int i = 0; i < 3; i++)
    {
        if (T[i] < 0) T[i] += 1.0;
        if (T[i] > 1) T[i] -= 1.0;
 
        if (T[i] < 1.0 / 6.0) 
            T[i] = P + ((Q - P) * 6 * T[i]);
        else if (1.0 / 6.0 <= T[i] && T[i] < 1.0 / 2.0)
            T[i] = Q;
        else if (1.0 / 2.0 <= T[i] && T[i] < 2.0 / 3.0)
            T[i] = P + ((Q - P) * (2.0 / 3.0 - T[i]) * 6);
        else
            T[i] = P;
 
        C[i] = Math.Max(0, Math.Min(255, (int)(255 * T[i])));
    }
 
    return Color.FromArgb(C[0], C[1], C[2]);
}
1
2 / 2 / 0
Регистрация: 14.10.2018
Сообщений: 122
25.11.2021, 15:18  [ТС]
Ого, огромное вам спасибо. Буду разбираться. Был уверен, что асе составляющие кроме одной нужно обнулять, хотя, если прямо поразмыслить, то это конечно довольно глупо. Буду исправляться
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.11.2021, 15:18
Помогаю со студенческими работами здесь

Как привязать цветовые координаты (rgb и hsl) к картинке
Подскажите пожалуйста!!! Как привязать цветовые координаты (rgb и hsl) к картинке в c++.

Преобразование изображения из цветовой модели RGB в модель HSL
Всем доброго времени суток! Я учусь на программиста, и мне очень нужна ваша помощь. Что нужно для преобразования изображения из...

GDI+ изменить насыщенность и яркость разложив RGB в HSL
не совсем понятно, как изменить у картинки насыщенность и яркость я взял пиксель в rgb, получил Color, и вытащил оттуда hue, saturation и...

Ошибка при переводе
Здравствуйте вообщем мне нужно перевести код с++ в си я попробовал и мне выдало вот такие ошибки main.c: In function ‘main’: ...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru