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

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

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

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

Заранее большое спасибо за пояснения!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.12.2011, 01:27
Ответы с готовыми решениями:

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

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

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

18
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
25.12.2011, 16:21
Вот самый простой вариант построения
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
можешь прокоментировать вкратце этот код?? не всё мне понятно. заранее спасибо
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
04.10.2012, 08:45
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
 Аватар для nio
6050 / 3460 / 336
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
04.10.2012, 10:15
Цитата Сообщение от DroidAn Посмотреть сообщение
И не пойму самой сути.
Суть гистограммы - подсчет количества пикселей для каждого уровня яркости.

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

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

переделать под winForm не составит труда. Я, к примеру, тогда бы использовал ZedGraph для вывода гистограммы.
1
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 21:01
Цитата Сообщение от 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
Колямбий, а разве нет библиотек по типу 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
Цитата Сообщение от Ev_Hyper Посмотреть сообщение
а разве нет библиотек по типу Aforge для С++?
есть opencv, но с ней у меня не получилось гистограмму построить правильную

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

просто любая запись с двойными плюсами разворачивается в обычную, как мне кажется в квадратных скобках должен быть индекс, массива, а получается какой то цвет, зачем?
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
13.06.2014, 21:54
Цитата Сообщение от Колямбий Посмотреть сообщение
а получается какой то цвет
Ну покажите уже тот участок, на С++
0
7 / 7 / 3
Регистрация: 18.12.2011
Сообщений: 137
13.06.2014, 22:14
Цитата Сообщение от 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
2444 / 1842 / 406
Регистрация: 15.12.2013
Сообщений: 8,243
13.06.2014, 22:19
Колямбий, пробуйте
C++
1
R[i][j]=Color.R;
Добавлено через 59 секунд
Стоп,не увидел,что массив одномерный.
0
Заблокирован
13.06.2014, 22:19
Цитата Сообщение от Колямбий Посмотреть сообщение
просто любая запись с двойными плюсами разворачивается в обычную, как мне кажется в квадратных скобках должен быть индекс, массива, а получается какой то цвет, зачем?
для построения гистограммы мы считаем частоты. Именно поэтому используется такая запись.
Для большего понимания, что происходит в том участке:
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;
}
Code
1
2
3
4
5
6
7
8
9
10
11
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
Цитата Сообщение от S_el Посмотреть сообщение
R[i][j]=Color.R;
спасибо, сейчас попробую, а почему каждый раз увеличивалось на единицу ++R?
0
2444 / 1842 / 406
Регистрация: 15.12.2013
Сообщений: 8,243
13.06.2014, 22:21
Колямбий, не стоит так делать,я невнимательно посмотрел на код
1
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
13.06.2014, 22:24
Цитата Сообщение от Колямбий Посмотреть сообщение
если писать ++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
привет, плиз можешь дать мне сам реализованный проект данной работы очень нужен!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.05.2016, 11:51
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru