Правильный ли код? Почему не рисует квадраты цвета?

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 05.01.2018 (Пт) 20:45

Здравствуйте! Всех с новым годом!
На днях написал небольшой код, чтобы можно было получать массив всех цветов, присутствующих в изображении. Проблема в том что я решил весь массив отобразить в виде квадратиков цвета в PictureBox, но он отрисовал не квадраты, а прямоугольники?!
Вторая проблема на изображении явно видны одинаковые цвета. Возникает вопрос правильно ли я код написал? Может кто нить посмотрит, да пояснит где я ошибся!

Внимание! Код не комментирован и не форматирован!

Инструкция по программе:
1.Нажимаете на кнопку "Get Color", программа через GetDIBits берет все изображение в массив и через CopyMemory переносит в массив Типа ARGB. Тем самым получаем массив с отдельными состовляющими A,R,G и B!
В конце операции показывает MsgBox с ARGB одной точки из изображения
2.Нажимаете на кнопку "Get All Color". Программа в заносит в массив все цвета изображения. Операция выполняет попиксельное сравнивание и занимает не мало времени (на одноядерном компе около 1 минуты). Поэтому дождитесь MsgBox "The end"
3.Нажимаете кнопку "Palitra". Здесь программа отрисовывает все цвета из полученого ранее массива.
4. Кнопка SetColor всего лишь увеличивает красный канал на 100%.
У вас нет доступа для просмотра вложений в этом сообщении.

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 06.01.2018 (Сб) 5:48

Прямоугольники получаются из-за того, что в массиве Clr() все цвета записаны по два раза подряд. Одинаковые цвета могут такими только казаться, но описываться разными величинами:
Код: Выделить всё
            R    G    B
Clr(i)   = 31   50   44
Clr(i+1) = 36   53   47
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 07.01.2018 (Вс) 17:50

pronto, ты был прав! Прямоугольники из-за двойственных значений в массиве. Занес массив Clr() в ListBox и сразу это стало видно. И насчет разных цветов тоже, хотя пока не проверял. Как исправлю исходник залью на форум авось кому сгодится)))

P.S.Вот исправил!
У вас нет доступа для просмотра вложений в этом сообщении.

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 07.01.2018 (Вс) 18:05

Don Leno, ты освоил битовые операции? Если нет, то я не хочу повторять ситуацию с темой Как сохранить миллион в более сжатом виде?. Потому что с их помощью можно ускорить код в 3000 (!!!) раз. Сперва я реализовал самый простой алгоритм — сравнение каждого пикселя с каждым. Действо занимало чуть больше трёх минут для всего изображения (1024 х 768). После переделывания алгоритма действо стало занимать 65 миллисекунд...
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 07.01.2018 (Вс) 18:44

pronto, это ведь тестовый проект и я его побыстрому набросал целеустремленно на результат. А насчет алгоритма это интересно, расскажи поподробнее. Сравнивать пиксели через оператор And? Разве будет быстрее?
Я пока не особо освоился с операциями, но главное понял суть их работы. Времени на программирование не так много для частой практики...

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 07.01.2018 (Вс) 18:51

Сравнивать полностью пиксели ведь не обязательно, ведь так?!
К примеру берем один цвет в Long это 16777215 (0,255,255,255) все биты у него установлены в 1. То есть достаточно считывать один бит из числа и проверять с другим битом из другого цвета, если же они не равны то идти к другому биту и тп Что то вроде побитового сравнения. Хотя по моему это даже медленнее.
А один байт из числа Long сравнивать вообще не нужно. Это альфа канал и он всегда 0. То есть вместо сравнивания 4 байт будет всего 3 байта, что надеюсь ускорит операцию.

P.S. Мысли вслух...

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3807
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Mikle » 07.01.2018 (Вс) 19:10

Какова конечная цель?
Цветов на картинке может оказаться очень много, тем более в jpg.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 07.01.2018 (Вс) 19:14

pronto советует применить битовые операции к моему проекту по работе с изображением чтобы ускорить процесс.

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 07.01.2018 (Вс) 19:25

Всего цветов может быть 16 777 216 (2^24). Представь, что бейсик позволяет объявлять массив бит, так чтобы можно было обращаться к каждому отдельному биту.
Код: Выделить всё
RawPalette(16777215) As Bit

Это очень простое допущение и является основной идеей. Остаётся организовать 1 проход по растру:
Код: Выделить всё
For i = 0 To UBound(ColorCode)
   RawPalette(ColorCode(i)) = 1
Next i

Проход по RawPalette() даёт собрать цвета, которые установили биты этого массива в единицу.
Для подряд идущих бит нет разницы, как они объявлены — As Bit или As Long. Единственное отличие второго варианта объявление от первого — количество элементов массива. В первом случае число элементов совпадает с необходимым числом. А во втором случае число элементов составит: 16777216 \ 32 - 1 = 524287. Вот тут-то и возникает необходимость использовать битовые операции, чтобы обратиться к нужному биту внутри 32-битного элемента.
З.Ы. Для справки. Цветов в предложенной картинке 122 042.
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 09.01.2018 (Вт) 18:47

pronto, вот написал! Пока не понимаю устанавливается ли бит в нужном месте?! Проверишь?
Код: Выделить всё
ReDim Allc(524287)
c = 0
For i = 0 To UBound(CBuf())
c = Fix(CBuf(i) / 32)
k = CBuf(i) - (c * 32)
Allc(c + 1) = Allc(c + 1) Or 2 ^ (k - 1)
Next i


Mikle тебе не ответил на твой вопрос! Конечная цель: собрав все цвета изображения сгруппировать по оттенкам, к примеру синий и все его оттенки и тп. Мне необходимо обрабатывать цвета в некоторых изображениях. К примеру у меня есть рисунок и нужно заменить в нем все оттенки красного на желтые. В программе будет опция каким цветом заменить выбраный.

To pronto Написал также считывание бита с массива. Но что-то коряво и с изображением sw.bmp не работает. В палитре должно быть 4 цвета, а он отрисовывает лишь зеленый. (sw.bmp нужно раскоментить взамен 1.jpg)
source:
У вас нет доступа для просмотра вложений в этом сообщении.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3807
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Mikle » 09.01.2018 (Вт) 22:52

Don Leno писал(а):Конечная цель: собрав все цвета изображения сгруппировать по оттенкам, к примеру синий и все его оттенки и тп. Мне необходимо обрабатывать цвета в некоторых изображениях. К примеру у меня есть рисунок и нужно заменить в нем все оттенки красного на желтые.

Если нужно заменить "все оттенки красного на желтые", то не нужно ничего "группировать по оттенкам", достаточно просто в один проход обойти все пиксели и те, которые подходят под определение "оттенки красного", изменить как требуется.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 10.01.2018 (Ср) 2:36

Mikle, ты конечно прав! Но хотелось бы научиться еще и отбирать цвета по оттенкам, вот я поставил такую себе задачу. Тем более мало ли где потом сгодится?

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3807
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Mikle » 10.01.2018 (Ср) 9:57

Для начала нужно дать определение "оттенок", например, "оттенок красного".

Скажем так - "цвет, в котором значение компоненты R превышает G и B".
Проверяем, вот цвет FFBF00: тест
Больше похоже на жёлтый.

Можно определить так: "цвет, в котором значение компоненты R превышает G и B более, чем вдвое".
Проверяем, вот цвет FF9090: тест
С виду - вполне себе красный, а под определение не подошёл.

К чему я всё это - ты решаешь задачу в то время, когда ещё не поставлено её условие. Поставь СТРОГО условие задачи, и тебе быстрее помогут в решении.

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 10.01.2018 (Ср) 11:24

Don Leno писал(а):
Код: Выделить всё
ReDim Allc(524287)
c = 0
For i = 0 To UBound(CBuf())
c = Fix(CBuf(i) / 32)
k = CBuf(i) - (c * 32)
Allc(c + 1) = Allc(c + 1) Or 2 ^ (k - 1)
Next i

Близко. Номер элемента вычисляется проще: c = CBuf(i) \ 32. Обрати внимание на оператор целочисленного деления «\». Прибавлять единицу нет надобности. Номер бита вычисляется очень оригинально... Здесь тебе нужен оператор Mod. Отнимать единицу тоже нет надобности (интересно, каковы были соображения при осуществлении этих операций (+/-)?). От возведения в степень можно нужно избавиться...
P.S. Для простоты понимания оттенков красного, ищи «куб RGB»
O, sancta simplicitas!

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение FireFenix » 10.01.2018 (Ср) 11:42

Mikle писал(а):Можно определить так

Мне кажется задача решается переводом RGB в HSV и отсечение по границам Hue :)
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3807
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Mikle » 10.01.2018 (Ср) 11:47

FireFenix писал(а):задача решается переводом RGB в HSV и отсечение по границам Hue

Да, как вариант. Просто я хочу, чтобы Don Leno определился, что же ему нужно.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 10.01.2018 (Ср) 19:32

Mikle мне необходимы группы оттенков видимого спектра. Т.е. которые видны человеком на экране. Если красный, то красный и не важно какие состовляющие его RGB. Суть найти их и сгруппировать под одной группой.
Представь себе яблоко с зеленым листочком. Яблоко это красно-желтое местами оранжевое. Так вот программа должна создать четыре группы - красный, желтый, оранжевый и зеленый. В итоге я могу сохранить эти группы в файл/массив (так как мне нужно). И потом оперировать с ними.
К примеру, возьмем другой рисунок и сохраним из него группу оттенков синего. Потом заменим красную группу на синию из файла, а оранжевую заменим зеленым, желтый оставим неизменным. Листочек зеленого заменим на красный и в итоге получим - сине-желтое яблоко с зелеными переходами и красный листочек на нем.
Ниже смотреть рисунок!
pronto спасибо за подсказки! Мне очень они сейчас нужны. А на счет плюса\минуса. То я отступая целое кол-во 32 битных групп перехожу на следующий индекс, в котором и будет записан бит. Мне ведь нужно, как я понимаю, записать бит в том месте, числом которое оно обозначено в массиве CBuf. Т.е. если в цвет 16777216, то и бит в массиве будет устанавливаться на этой же позиции. Ведь массив AllC() содержит просто упорядоченые биты каждого цвета.
Прошу прощения, код был немного уже подредактирован, после первого моего сообщения!
было:
Код: Выделить всё
Allc(c + 1) = Allc(c + 1) Or 2 ^ (k - 1)

стало:
Код: Выделить всё
Allc(c + 1) = Allc(c + 1) Or (2 ^ k) - 1

Только как избавиться от степени, если изначально она неизвестна?!

Про функцию Mod и \ , вот набросок:
Код: Выделить всё
c = CBuf(i) \ 32
k = CBuf(i) mod  32

Кстати, вот если в исоднике MK2 Убрать из степени -1 и загружать рисунок 1.jpg то вылетает ошибка переполнения, а загрузив рисунок sw.bmp считывание палитры рисует правильно, но если оставить минус один, тогда палитра рисует лишь один цвет!? В чем проблема?
У вас нет доступа для просмотра вложений в этом сообщении.

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 11.01.2018 (Чт) 11:30

Номера элементов в Allc начинаются с ноля. Степеней всего сколько? Сколько бит в Long? Нужен массив из 32-х Long'ов, в каждом из которых будет установлен соответствующий бит:
Код: Выделить всё
Dim pow2(31) As Long
Dim i As Long

For i = 0 To UBound(pow2) - 1
   pow2(i) = 2 ^ i
Next i

' установка 31-го бита
pow2(i) = pow2(i) Or &H80000000
O, sancta simplicitas!

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение FireFenix » 11.01.2018 (Чт) 13:12

Don Leno писал(а): мне необходимы группы оттенков видимого спектра.

RGB модель описывает цвет только видимого спектра

Don Leno писал(а):Представь себе яблоко с зеленым листочком. Яблоко это красно-желтое местами оранжевое. Так вот программа должна создать четыре группы - красный, желтый, оранжевый и зеленый. В итоге я могу сохранить эти группы в файл/массив (так как мне нужно). И потом оперировать с ними.
К примеру, возьмем другой рисунок и сохраним из него группу оттенков синего. Потом заменим красную группу на синию из файла, а оранжевую заменим зеленым, желтый оставим неизменным. Листочек зеленого заменим на красный и в итоге получим - сине-желтое яблоко с зелеными переходами и красный листочек на нем.

Мне кажется у тебя не совсем корректно поставлено условие...
Ты рассматриваешь картинку как предустановленную палитру, но полноценные текстуры/картинки/фотографии не совсем не такие, а они оперируют всем цветовым спектром rgb.
Как пример гистограмма - https://image.prntscr.com/image/8qSMg9G ... 0GsmQ.jpeg . Там где красный преобладает - да ок, а где нет (первая половина спектра)? - уже никак

Т.е. да, можно определить цветовую палитру и на основе её корректировать результирующее фото, но будет очень много погрешностей.

По хорошему то, что ты хочешь называется Color Grading и обычно для него используются LUT таблицы, которые описывают изменение цветового пространства
Пример в UE - https://docs.unrealengine.com/latest/IN ... UsingLUTs/
Пример как Unity ассет - https://www.assetstore.unity3d.com/en/#!/content/50070
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 3807
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Mikle » 11.01.2018 (Чт) 13:57

FireFenix писал(а):можно определить цветовую палитру и на основе её корректировать результирующее фото, но будет очень много погрешностей.

В том числе такие: мы умудрились разделить яблоко на красный и оранжевый участки, в исходном изображении граница между ними плавная, но после РАЗДЕЛЬНОЙ обработки этих участков на границе появится шов.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 11.01.2018 (Чт) 16:46

Так в том то и дело!!! Пусть не совсем корректно и со швом будет обрабатываться изображение! Программа лишь и будет относится к грубому инструменту обработки изображения (вообще то пишу для себя). Но и очень хочется научиться!
Вот еще вопросы:
Как увеличить/уменьшить яркость изо(изображение)
Как сделать насыщение цвета, как в фотошопе.
Как сделать контраст?
To pronto я так и сделаю! Только помоги с ошибками чтения из массива. Заносится вроде все верно, а считывает неправильно. Но я и до чтения доберусь, сейчас с кодом занесения разберусь и все!

Вот кстати, а зачем ты минусешь 1 от Ubound, ведь тогда получается 31 бит, а не 32:

Код: Выделить всё
For i = 0 To UBound(pow2) - 1
   pow2(i) = 2 ^ i
Next i

Проверил, закоментив "-1", в итоге выскакивает ошибка переполнения, как и у меня! Так как же быть с 32 битом?!
Добавил код как в запись битов, так и в их чтение - сразу все лаги прошли! Видать там с этим возведением в степень какие то ошибки были. А то палитра цвет повторяла длиными линиями, и показывала не все цвета!
Подсчитал 118490 цветов всего нашел?!
Ниже откомментированый исходник:
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось Don Leno 11.01.2018 (Чт) 17:35, всего редактировалось 1 раз.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение FireFenix » 11.01.2018 (Чт) 17:09

Вот еще вопросы:

Переводишь в HSV , регулируешь компоненты, переводишь обратно в требуемый формат
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 11.01.2018 (Чт) 17:53

FireFenix, спс формулы увидел))) Буду пробовать!

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 11.01.2018 (Чт) 17:53

' установка 31-го бита
pow2(i) = pow2(i) Or &H80000000
Где?
Нумерация бит начинается с НОЛЯ.
O, sancta simplicitas!

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 11.01.2018 (Чт) 20:48

Pronto, теперь понятно куда делся 32 бит)))) Это я поторопился!
Исправил в исходнике и теперь выдает 122042 найденых цветов!
Подскажте пжлста, как бы мне к моему PictureBox сделать просмотр всех цветов, а не только тех что помещаются на экране? Прошу только в теории)))

pronto
Постоялец
Постоялец
 
Сообщения: 579
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение pronto » 12.01.2018 (Пт) 13:40

Я бы сделал что-то вроде страничного просмотра. Типа «Page Up» и «Page Down». По «Page Down» прибавлять количество цветов, которое помещается на «странице». По «Page Up» — отнимать.
O, sancta simplicitas!

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение FireFenix » 12.01.2018 (Пт) 15:22

Don Leno писал(а):Подскажте пжлста, как бы мне к моему PictureBox сделать просмотр всех цветов, а не только тех что помещаются на экране? Прошу только в теории)))

Брать значения цвета не с экрана/окна/контрола, а с самого изображения
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 311
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Правильный ли код? Почему не рисует квадраты цвета?

Сообщение Don Leno » 13.01.2018 (Сб) 22:16

FireFenix Так у меня и так с массива берутся значения! Терь понятно брать по определенному кол-во и выводить на экран)))
pronto А про клавиши спс отдельно! удобно юзать)))


Вернуться в Мультимедиа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

    TopList