Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.79/131: Рейтинг темы: голосов - 131, средняя оценка - 4.79
7 / 7 / 0
Регистрация: 18.11.2011
Сообщений: 150
1

Гистограмма изображения по компонентам RGB

23.12.2011, 01:27. Показов 25052. Ответов 18
Метки нет (Все метки)

Здравствуйте! Пытаюсь построить гистограмму по трём цветовым компонентам из исходного изображения. И не пойму самой сути. Я верно понимаю, что в итоге в гистограмме будет отрисовано три столбика (для каждого цвета)? И как вычисляется уровень столбиков гистограммы?

Заранее большое спасибо за пояснения!
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.12.2011, 01:27
Ответы с готовыми решениями:

Гистограмма CMYK/RGB - некорректный перевод из CMYK в RGB
Возникла проблема с правильностью перевода из RGB в CMYK. Все переменные до самого конца - double,...

Получения температуры из RGB изображения
Здравствуйте, столкнулся с такой проблемой! Имею RGB изображение детали, которая разогрета до...

Преобразование изображения из RGB в CMYK
При переводе изображения из RGB в CMYK не получается записать рассчитанные для CMYK значения в...

Программа деления изображения по каналам RGB
Помогите пожалуйста написать программу деления изображения по каналам RGB которая позволяет: 1)...

18
Эксперт JavaЭксперт С++
8369 / 3591 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
25.12.2011, 16:21 2
Вот самый простой вариант построения
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
public Image CalculateBarChart (Image image)
{
    Bitmap barChart = null;
    if (image != null) 
    {
        int width = 768, height = 600;
        Bitmap bmp = new Bitmap (image);
        barChart = new Bitmap (width, height);
        int[] R = new int[256];
        int[] G = new int[256];
        int[] B = new int[256];
        int i, j;
        Color color;
        for (i = 0; i < bmp.Width; ++i)
            for (j = 0; j < bmp.Height; ++j) 
            {
                color = bmp.GetPixel (i, j);
                ++R[color.R];
                ++G[color.G];
                ++B[color.B];
            }
        int max = 0;
        for (i = 0; i < 256; ++i)
        {
            if (R[i] > max)
                max = R[i];
            if (G[i] > max)
                max = G[i];
            if (B[i] > max)
                max = B[i];
        }
        double point = (double)max / height;
        for (i = 0; i < width - 3; ++i) 
        {
            for (j = height - 1; j > height - R[i / 3] / point; --j) 
            {
                barChart.SetPixel (i, j, Color.Red);
            }
            ++i;
            for (j = height - 1; j > height - G[i / 3] / point; --j) 
            {
                barChart.SetPixel (i, j, Color.Green);
            }
            ++i;
            for (j = height - 1; j > height - B[i / 3] / point; --j) 
            {
                barChart.SetPixel (i, j, Color.Blue);
            }
        }
    } else
        barChart = new Bitmap (1, 1);
    return barChart;    
}
1
dimaasis
03.10.2012, 23:42 3
можешь прокоментировать вкратце этот код?? не всё мне понятно. заранее спасибо
Эксперт JavaЭксперт С++
8369 / 3591 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
04.10.2012, 08:45 4
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
public Image CalculateBarChart (Image image)
{
    Bitmap barChart = null;
    if (image != null) 
    {
        // определяем размеры гистограммы. В идеале, ширина должны быть кратна 768 - 
        // по пикселю на каждый столбик каждого из каналов
        int width = 768, height = 600;
        // получаем битмап из изображения
        Bitmap bmp = new Bitmap (image);
        // создаем саму гистограмму
        barChart = new Bitmap (width, height);
        // создаем массивы, в котором будут содержаться количества повторений для каждого из значений каналов.
        // индекс соответствует значению канала
        int[] R = new int[256];
        int[] G = new int[256];
        int[] B = new int[256];
        int i, j;
        Color color;
        // собираем статистику для изображения
        for (i = 0; i < bmp.Width; ++i)
            for (j = 0; j < bmp.Height; ++j) 
            {
                color = bmp.GetPixel (i, j);
                ++R[color.R];
                ++G[color.G];
                ++B[color.B];
            }
        // находим самый высокий столбец, чтобы корректно масштабировать гистограмму по высоте
        int max = 0;
        for (i = 0; i < 256; ++i)
        {
            if (R[i] > max)
                max = R[i];
            if (G[i] > max)
                max = G[i];
            if (B[i] > max)
                max = B[i];
        }
        // определяем коэффициент масштабирования по высоте
        double point = (double)max / height;
        // отрисовываем столбец за столбцом нашу гистограмму с учетом масштаба
        for (i = 0; i < width - 3; ++i) 
        {
            for (j = height - 1; j > height - R[i / 3] / point; --j) 
            {
                barChart.SetPixel (i, j, Color.Red);
            }
            ++i;
            for (j = height - 1; j > height - G[i / 3] / point; --j) 
            {
                barChart.SetPixel (i, j, Color.Green);
            }
            ++i;
            for (j = height - 1; j > height - B[i / 3] / point; --j) 
            {
                barChart.SetPixel (i, j, Color.Blue);
            }
        }
    } else
        barChart = new Bitmap (1, 1);
    return barChart;    
}
0
6032 / 3440 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
04.10.2012, 10:15 5
Цитата Сообщение от DroidAn Посмотреть сообщение
И не пойму самой сути.
Суть гистограммы - подсчет количества пикселей для каждого уровня яркости.

Цитата Сообщение от DroidAn Посмотреть сообщение
Я верно понимаю, что в итоге в гистограмме будет отрисовано три столбика (для каждого цвета)?
В основном понимании гистограмма подразумевает оценку яркости изображения в целом, т.е. сначала изображение преобразуется в оттенки серого, затем строится его гистограмма. Но допускается и вычисление гистограмм на каждый цветовой канал. Принцип тот же - подсчет количества пикселелей каждого уровня яркости.
Не совсем понимаю, что ты имел ввиду под столбиками.
Изображение гистограммы - это двумерный график, по оси Х имеет 255 значений (для каждого уровня яркости), по оси Y указывается количество пикселей (как правило пропорционально уменьшается для удобства восприятия). При построении гистограммы по каналам для каждого цвета рисуется отдельный график.
Миниатюры
Гистограмма изображения по компонентам RGB  
2
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 20:45 6
Цитата Сообщение от M128K145 Посмотреть сообщение
++R[color.R];
ни как не могу понять, color.R - это установка цвета?
0
2425 / 1826 / 403
Регистрация: 15.12.2013
Сообщений: 8,006
13.06.2014, 20:49 7
Цитата Сообщение от Колямбий Посмотреть сообщение
ни как не могу понять, color.R - это установка цвета?
Это получение значения красной компоненты пикселя color.
1
Заблокирован
13.06.2014, 20:52 8
Колямбий, если вам не принципиально что использовать, то вот решение в WPF:

http://www.csharpcoderr.com/20... e-wpf.html

переделать под winForm не составит труда. Я, к примеру, тогда бы использовал ZedGraph для вывода гистограммы.
1
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 21:01 9
Цитата Сообщение от S_el Посмотреть сообщение
Это получение значения красной компоненты пикселя color
подскажите как эту запись ++R[color.R] преобразовать в с++

Добавлено через 1 минуту
Цитата Сообщение от Ev_Hyper Посмотреть сообщение
если вам не принципиально что использовать, то вот решение в WPF:
http://www.csharpcoderr.com/20... e-wpf.html
переделать под winForm не составит труда. Я, к примеру, тогда бы использовал ZedGraph для вывода гистограммы.
было бы не принципиально, но весь проект на С++, хотя сам больше люблю шарп
0
Заблокирован
13.06.2014, 21:11 10
Колямбий, а разве нет библиотек по типу Aforge для С++?
Цитата Сообщение от Колямбий Посмотреть сообщение
подскажите как эту запись ++R[color.R] преобразовать в с++
в плюсах с изображениями не работал, но, разве в этой записи будет что-то отличаться? Если, конечно есть свойство R у Color. Если нету, то может помочь:
http://msdn.microsoft.com/ru-r... s.90).aspx
http://sotnyk.com/2013/10/26/r... el-csharp/
там есть работа с изображениями более быстрая + без привязки к методу GetPixel
0
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 21:42 11
Цитата Сообщение от Ev_Hyper Посмотреть сообщение
а разве нет библиотек по типу Aforge для С++?
есть opencv, но с ней у меня не получилось гистограмму построить правильную

Цитата Сообщение от Колямбий Посмотреть сообщение
++R[color.R]
в том то и проблема что из всего кода не работает именно это.

просто любая запись с двойными плюсами разворачивается в обычную, как мне кажется в квадратных скобках должен быть индекс, массива, а получается какой то цвет, зачем?
0
870 / 768 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
13.06.2014, 21:54 12
Цитата Сообщение от Колямбий Посмотреть сообщение
а получается какой то цвет
Ну покажите уже тот участок, на С++
0
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 22:14 13
Цитата Сообщение от MrCold Посмотреть сообщение
Ну покажите уже тот участок, на С++
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
                 int* R = new int[256];
                 int* G = new int[256];
                 int* B = new int[256];
                 int i, j;
                 Color color;
                 for (i = 0; i < myBitmap2->Width; ++i)
                     for (j = 0; j < myBitmap2->Height; ++j) 
                     {
                         color = myBitmap2->GetPixel (i, j);
                         ++R[color.Red];
                         ++G[color.Green];
                         ++B[color.Blue];
                     }
если писать ++R[color.Red] то ошибка
error C2677: binary '[' : no global operator found which takes type 'System:rawing::Color' (or there is no acceptable conversion)
если писать ++R[color->Red] то такая же ошибка
а если писать ++R[color::Red] то ошибка
error C2510: 'color' : left of '::' must be a class/struct/union
error C2065: 'Red' : undeclared identifier
0
2425 / 1826 / 403
Регистрация: 15.12.2013
Сообщений: 8,006
13.06.2014, 22:19 14
Колямбий, пробуйте
C++
1
R[i][j]=Color.R;
Добавлено через 59 секунд
Стоп,не увидел,что массив одномерный.
0
Заблокирован
13.06.2014, 22:19 15
Цитата Сообщение от Колямбий Посмотреть сообщение
просто любая запись с двойными плюсами разворачивается в обычную, как мне кажется в квадратных скобках должен быть индекс, массива, а получается какой то цвет, зачем?
для построения гистограммы мы считаем частоты. Именно поэтому используется такая запись.
Для большего понимания, что происходит в том участке:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    int arr[10] = {1,1,2,2,3,4,4,4,1,1};
    int counter[10];
    //зануляем
    for (int i=0;i<10;i++)
            counter[i]=0;
    //считаем
    for (int i=0;i<10;i++)
            counter[arr[i]]++;
    //вывод на консоль
    for (int i=0;i<10;i++)
            cout<<i<<"   "<<counter[i]<<endl;
    return 0;
}
Код
0   0
1   4
2   2
3   1
4   3
5   0
6   0
7   0
8   0
9   0
Для продолжения нажмите любую клавишу . . .
тут происходит тоже самое.

Если ошибка с конвертацией, то выполняйте это действие явно.
2
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 22:20 16
Цитата Сообщение от S_el Посмотреть сообщение
R[i][j]=Color.R;
спасибо, сейчас попробую, а почему каждый раз увеличивалось на единицу ++R?
0
2425 / 1826 / 403
Регистрация: 15.12.2013
Сообщений: 8,006
13.06.2014, 22:21 17
Колямбий, не стоит так делать,я невнимательно посмотрел на код
1
Эксперт JavaЭксперт С++
8369 / 3591 / 419
Регистрация: 03.07.2009
Сообщений: 10,708
13.06.2014, 22:24 18
Цитата Сообщение от Колямбий Посмотреть сообщение
если писать ++R[color.Red] то ошибка
а вы напишите так, как написано в примере:
C++
1
2
3
                ++R[(int)color.R];
                ++G[(int)color.G];
                ++B[(int)color.B];
Цитата Сообщение от Колямбий Посмотреть сообщение
спасибо, сейчас попробую, а почему каждый раз увеличивалось на единицу ++R?
потому что это, по сути, счетчик, который считает сколько раз у вас встретился пиксель с таким значением цветового канала
1
0 / 0 / 0
Регистрация: 04.10.2015
Сообщений: 9
28.05.2016, 11:51 19
привет, плиз можешь дать мне сам реализованный проект данной работы очень нужен!
0
28.05.2016, 11:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.05.2016, 11:51

Реализовать фильтрацию цветного RGB-изображения
Реализовать фильтрацию цветного RGB-изображения преобразовав в пространство HSI скользящей...

Сохранение RGB изображения после преобразования в файл *.bmp формата
Вот такая ситуация у меня: Есть bmp рисунок и мне нужно сделать с него 24-битную картинку. ...

Как графический bmp-файл вне зависимости от типа изображения привести к RGB изображению?
как графический *.bmp файл в не зависимости от типа изображения которое отрываю ( или серая шкала,...

Трехмерная гистограмма яркостей цветного изображения
Люди добрые, помогите на C++ разработать программу рассчитывающую трехмерную гистограмму яркостей...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru