Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.233.150] |
|
Сообщ.
#1
,
|
|
|
Дано PDF
Конвертирую в JPG Надо определить сколько точек белых, сколько цветных и сколько принадлежажщих Grayscale Всю голову сломал как сделать? |
Сообщ.
#2
,
|
|
|
Да просто же:
1.Читаете JPG, скажем, через GDI+ в буфер, в картинку. 2.Там попиксельно бежите по ней, получая цвет каждого. 3.Определив для себя какую область RGB-куба назовём "белой", "серой", "цветной", записываем плюс единичку в ту переменную. 4.В конце выдаём количество или соотношение оных. |
Сообщ.
#3
,
|
|
|
Цитата Славян @ Да просто же: 1.Читаете JPG, скажем, через GDI+ в буфер, в картинку. 2.Там попиксельно бежите по ней, получая цвет каждого. 3.Определив для себя какую область RGB-куба назовём "белой", "серой", "цветной", записываем плюс единичку в ту переменную. 4.В конце выдаём количество или соотношение оных. 1. понятно 2. при размере 3600*3000 сколько времени понадобится на 1 картину? Я имел ввиду оптимизированную функцию. 3. Вот самое сложное RGB. Не могу понять какие считать ч/б, какие к цв. Если взять за исходник скан то там белого практически не будет. 4. Это самое простое. По факту уточнение: 1. быстрое чтение попиксельное 2. RGB что ч/б что цвет. |
Сообщ.
#4
,
|
|
|
Время - менее секунды
Попиксельно - TBitmap.Scanline или библиотечка TQuickPixels Для определения цветности перевести RGB в HSV/HSL (функция в Delphi есть) или использовать другую метрику цветовой насыщенности. Если файлов много, и производительности будет не хватать, можно использовать библиотеку OpenCV для загрузки и конвертации (cvConvert) (но на порядок этим не ускорить) |
Сообщ.
#5
,
|
|
|
Цитата MBo @ пример можно? |
Сообщ.
#6
,
|
|
|
Цитата DeZik @ Одна машинная инструкция. Быстрее - почти некуда (шейдеры ГП разве что?).1. быстрое чтение попиксельное bmpPNG->LockBits( &rect, Gdiplus::ImageLockModeRead, PixelFormat32bppPARGB, &bitmapData); // меняем красную и синюю компоненты for( rgba *src=(rgba *)bitmapData.Scan0; h>0; h--) ... Цитата DeZik @ 2. RGB что ч/б что цвет. rgba *p = ((rgba *)bitmapData.Scan0)[adres]; if( abs(p->red - p->blue) + abs(p->blue - p->green) + abs(...)<степень ) p = степеньСерого; else p = цветнаяКажись; |
Сообщ.
#7
,
|
|
|
Цитата Славян @ rgba *p = ((rgba *)bitmapData.Scan0)[adres]; if( abs(p->red - p->blue) + abs(p->blue - p->green) + abs(...)<степень ) p = степеньСерого; else p = цветнаяКажись; Что есть RGBA и т.п. внятный пример, а не обрывок. зачем мы "// меняем красную и синюю компоненты" |
Сообщ.
#8
,
|
|
|
rgba - структура, состоящая из 4 байт:
struct { char r,g,b,a; } Замена компонент - просто обрывок из левого кода, чтобы показать, как картинка блокируется, а потом получаем прямой доступ к пикселам. |
Сообщ.
#9
,
|
|
|
Цитата Славян @ struct { char r,g,b,a; мы по-моему на delphi пишем здесь, а не на др. языках. я просил привести пример законченной функции сканирования и законченной функции анализа. |
Сообщ.
#10
,
|
|
|
1. Я счёл, что на Паскаль вы запросто переведёте.
2. Скажите номер сообщения, где вы просите "привести пример законченной функции сканирования и законченной функции анализа"?.. |
Сообщ.
#11
,
|
|
|
Цитата Славян @ 1. Я счёл, что на Паскаль вы запросто переведёте. к сожалению нет Цитата Славян @ 2. Скажите номер сообщения, где вы просите "привести пример законченной функции сканирования и законченной функции анализа"?.. Цитата DeZik @ внятный пример, а не обрывок. |
Сообщ.
#12
,
|
|
|
Увы, но все примеры у меня - Си'шные. Если не подходят, то - пардон.
|
Сообщ.
#13
,
|
|
|
Какая цель преследуется? Это учебная задача или практическая?
Цитата DeZik @ Дано PDF Конвертирую в JPG Почему JPG? Это обязательное условие или просто так захотелось? Цитата DeZik @ Надо определить сколько точек белых, сколько цветных и сколько принадлежажщих Grayscale Технически, белый тоже относится к Grayscale... Цитата DeZik @ Не могу понять какие считать ч/б, какие к цв. Если взять за исходник скан то там белого практически не будет. Grayscale это когда R=G=B иначе это цвет, но, есть понятие абсолютного значения цвета с точки зрения RGB, где белым цветом будет FFFFFF, а есть понятие визуального восприятия, когда мы смотрим на скан чертежа и понимаем, что это белый лист и черные линии, а в абсолютных значениях там нет ни белого ни черного. Так что без уточнений по задаче тяжело что-то советовать. |
Сообщ.
#14
,
|
|
|
Цитата x128 @ Grayscale это когда R=G=B иначе это цвет, но, есть понятие абсолютного значения цвета с точки зрения RGB, где белым цветом будет FFFFFF, а есть понятие визуального восприятия, когда мы смотрим на скан чертежа и понимаем, что это белый лист и черные линии, а в абсолютных значениях там нет ни белого ни черного. Ну это проще. 1. Переводим RGB в HSV. 2. Ищем на скане цвет с самой низкой S и самой высокой V. 3. Все достаточно близкие по S и V к нему цвета считаем белым. 4. Ищем цвет с самыми низкими S и V. 5. Все достаточно близкие по S и V к нему цвета считаем чёрным. S - контраст, V - яркость, H можно игнорировать. |
Сообщ.
#15
,
|
|
|
Цитата Писатель @ Ну это проще. 1. Переводим RGB в HSV. 2. Ищем на скане цвет с самой низкой S и самой высокой V. 3. Все достаточно близкие по S и V к нему цвета считаем белым. 4. Ищем цвет с самыми низкими S и V. 5. Все достаточно близкие по S и V к нему цвета считаем чёрным. S - контраст, V - яркость, H можно игнорировать. Рабочий пример пожалуйста |
Сообщ.
#16
,
|
|
|
Цитата Писатель @ Ну это проще. Это кажется простым, пока дело не дойдет до практической реализации... Уже в п.1 могут возникнуть вопросы и для этого достаточно одного контрастного пиксела. Далее начнутся вопросы в п.2 при выборе порога, что считать "достаточно близким"? Ярким примером будет известная иллюзия с шахматной доской, где клетки А и B имеют одинаковый цвет, хотя мы точно можем сказать какая клетка темная и какая светлая. |
Сообщ.
#17
,
|
|
|
Цитата DeZik @ Рабочий пример пожалуйста Пример функции, переводящей RGB в HSV - можно. type TClRGB = record R: byte; G: byte; B: byte; end; TClHSV = record H: real; S: real; V: real; end; function RGBToHSV(vxRGB: TClRGB): TClHSV; var vyHSV: TClHSV; maxvx, minvx: byte; begin if (vxRGB.R>=vxRGB.G) and (vxRGB.R>=vxRGB.B) then maxvx:=vxRGB.R else if (vxRGB.G>=vxRGB.R) and (vxRGB.G>=vxRGB.B) then maxvx:=vxRGB.G else if (vxRGB.B>=vxRGB.R) and (vxRGB.B>=vxRGB.G) then maxvx:=vxRGB.B; if (vxRGB.R<=vxRGB.G) and (vxRGB.R<=vxRGB.B) then minvx:=vxRGB.R else if (vxRGB.G<=vxRGB.R) and (vxRGB.G<=vxRGB.B) then minvx:=vxRGB.G else if (vxRGB.B<=vxRGB.R) and (vxRGB.B<=vxRGB.G) then minvx:=vxRGB.B; if minvx=maxvx then vyHSV.H:=0 else if (maxvx=vxRGB.R) and (vxRGB.G>=vxRGB.B) then vyHSV.H:=60*(vxRGB.G-vxRGB.B)/(maxvx-minvx) else if (maxvx=vxRGB.R) and (vxRGB.G<vxRGB.B) then vyHSV.H:=60*(vxRGB.G-vxRGB.B)/(maxvx-minvx)+360 else if (maxvx=vxRGB.G) then vyHSV.H:=60*(vxRGB.B-vxRGB.R)/(maxvx-minvx)+120 else if (maxvx=vxRGB.B) then vyHSV.H:=60*(vxRGB.R-vxRGB.G)/(maxvx-minvx)+240; if maxvx=0 then vyHSV.S:=0 else vyHSV.S:=1-minvx/maxvx; vyHSV.V:=maxvx/255; Result:=vyHSV; end; А остальное - вряд ли, т.к. это сильно зависит от конкретных условий задачи. Цитата x128 @ Это кажется простым, пока дело не дойдет до практической реализации... Уже в п.1 могут возникнуть вопросы и для этого достаточно одного контрастного пиксела. Далее начнутся вопросы в п.2 при выборе порога, что считать "достаточно близким"? Это да. Но тут вряд ли можно сразу найти универсальное решение для общего случая. Надо хотя бы знать, что это за сканы на входе. Если это какие-то фотографии или иллюстрации, то, возможно, что чисто чёрного и белого на них вобще не будет. И тогда этот алгоритм тоже не подойдёт. |
Сообщ.
#18
,
|
|
|
Цитата Писатель @ S - контраст, V - яркость, H можно игнорировать. С каких это пор? H - Hue (цветовой тон), S - Saturation (насыщенность), V - Value (значение цвета, яркость) https://ru.wikipedia.org/wiki/HSV_(%D1%86%D...B5%D0%BB%D1%8C) Какой у одной точки может быть контраст? Контраст это по определению разность между чем-то. |