Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 |

 

  Вопрос: Попиксельное сравнение картинок Добавлено: 07.06.10 13:36  

Автор вопроса:  Spiritsun
Облазил инет, ничо толкового не нашел. Помогите, пж., как очень быстро сравнить битмап в памяти? Средствами getpixel через цыклы - это долго. Пробовал Object.Equals, он сравнивает теги, а не нутро. Может есть какие внутренние команды, которые, например, сравнивали бы битовые представления объектов в памяти не трогая теги?

Куски имеют одинаковый размер. Интересует только нутро.

Ответить

  Ответы Всего ответов: 28  

Номер ответа: 1
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #1 Добавлено: 07.06.10 14:45

public System.IntPtr Scan0 { set; get; }
    Member of System.Drawing.Imaging.BitmapData

Summary:
Gets or sets the address of the first pixel data in the bitmap. This can also be thought of as the first scan line in the bitmap.

Returns:
The address of the first pixel data in the bitmap.


Тебе надо копать в эту сторону.. Используя эту фичу, ты получишь указатель на первый байт картинки в памяти, зная размеры картинки и ее глубину цвета ты сможешь создать байтовый массив нужного размера и скопировать в него картинку из памяти одним махом.. Таким образом ты получишь байтовый массив в котором представлена картинка.. Все что тебе останется - это лишь пробежаться одним циклом по массивам и сравнить байты. Если хоть одна пара байт различается то значит картинки не равны..
Если пишешь на С# и умеешь юзать unsafe код с указателями, то даже копировать ничего никуда не надо.. Надо будет лишь залочить картинки в памяти и провести сравнение прям на месте..

Ответить

Номер ответа: 2
Автор ответа:
 Spiritsun



Вопросов: 15
Ответов: 44
 Профиль | | #2 Добавлено: 07.06.10 16:08
Ага, хороший совет, пасиб. А есть ли команда сравнения блоков памяти? Ну чтоб не юзать циклы. Или как вариант не блоков памяти, а массивы, если обе картинки загнать туда.

Ответить

Номер ответа: 3
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #3 Добавлено: 07.06.10 16:35
Есть Enumerable.SequenceEqual
Поскольку работает через IEnumerable, то работать будет медленно, в место этого лучше сделать обычным циклом - будет быстрее.
Также можно еще быстрее сделать, если использовать unsafe указатели - не будет проверки выхода за границы массива.

Ответить

Номер ответа: 4
Автор ответа:
 Сергей



ICQ: 558230345 

Вопросов: 7
Ответов: 91
 Профиль | | #4 Добавлено: 07.06.10 16:36
попробуй посчитать контрольную сумму каждого рисунка и сравнить их

Ответить

Номер ответа: 5
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #5 Добавлено: 08.06.10 14:04
контрольная сумма здесь не нужна

Ответить

Номер ответа: 6
Автор ответа:
 Сергей



ICQ: 558230345 

Вопросов: 7
Ответов: 91
 Профиль | | #6 Добавлено: 08.06.10 16:53
контрольная сумма здесь не нужна

Почему? Вопрос ведь в сравнении двух битмапов а не в выявлении различий. Посчитать контрольную сумму быстрее чем перебрать массив пикселей. Исравнить две суммы проще и быстрее.

Ответить

Номер ответа: 7
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #7
Добавлено: 08.06.10 18:10
Чтобы посчитать контрольную сумму, нужно пройтись по всему массиву. Если в файле всего одно отличие, по матожиданию достаточно пройти половину массива.

Ответить

Номер ответа: 8
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #8 Добавлено: 08.06.10 18:28
Посчитать контрольную сумму быстрее чем перебрать массив

А ну ка, просвяти.. как ты собираешься считать контрольную сумму картинки при условии что у них одинаковый размер?

Ответить

Номер ответа: 9
Автор ответа:
 



Администратор

ICQ: 278109632 

Вопросов: 42
Ответов: 3949
 Web-сайт: domkratt.com
 Профиль | | #9
Добавлено: 08.06.10 19:06
А какая разница, какой у них размер? КоHрольная сумма будет разной при разности хоть одного бита.

Ответить

Номер ответа: 10
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #10 Добавлено: 08.06.10 19:21
в том то и фишка, что автор каким то образом хочет посчитать сумму без испоьзования циклов.. вот мне и интересно как..

Ответить

Номер ответа: 11
Автор ответа:
 VβÐUηìt



Вопросов: 246
Ответов: 3333
 Web-сайт: смекаешь.рф
 Профиль | | #11
Добавлено: 08.06.10 20:31
oO Просвятите, если я в чем то не прав:
В попу контрольную сумму (буэ). Туда же циклы (буээээээ!). Берем картинку А и картинку Б. Сначала сравниваем их размеры - если не совпадают - False. Затем, если они совпадают, накладываем А на другое с помощью BitBlt(.NET - DrawImageUnstretched) с битовой операцией такой, чтобы получалась разница (хоть какая-то, не помню там уже что именно, помню, что есть что-то такое :) ). Так вот, таким образом, получаем изображение, на котором отмечены только несовпадающие пиксели. То есть, если такой-то пиксель васи А равен соответствующему пикселю васи Б, то выбранная нами (не случайно) битовая операция сделает что-нибудь, обращающее цвет этого пикселя в константу. Дальше делаем SetStretchBltMode (.NET - Smoothing = Smoothing.HighQuality, или как там), и StretchBlt (.NET - DrawImage) на битмап с новыми значениями ширины 1 и высоты 1, то есть ужимаем нашего васю в один пиксель. Далее смотрим: если, допустим, наша битовая операция делал все одинаковые пиксели черными (как наложение "разница" в фотошопе), а неодинаковые - нечерными (какими-нибудь), то степень отличия картинок изменяется отличием цвета новоиспеченного пикселя от черного цвета. Ну как? Понятно, что способ не очень точен (на изображениях от 16x16 пикселей :) ), но зато, я полагаю, работает на порядки быстрее двух циклов. Остается только уточнить, есть ли хороший, годный битовый фильтр наложения для этой расты (не удержался). Смекнули?

Ответить

Номер ответа: 12
Автор ответа:
 Сергей



ICQ: 558230345 

Вопросов: 7
Ответов: 91
 Профиль | | #12 Добавлено: 09.06.10 09:53
есть подозрение, что вычисление контрольной суммы двух файлов стандартными средствами будет быстрее, чем "ручной" перебор двух массивов и пошаговое сравнение элементов массива. Во всяком случае из опыта это так. Хотя зависит от того, какой алгоритм подсчета используется.

Ответить

Номер ответа: 13
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #13 Добавлено: 09.06.10 10:37
Сергей пишет:
Посчитать контрольную сумму быстрее чем перебрать массив пикселей

неверно

Сергей пишет:
Исравнить две суммы проще и быстрее

верно, при условии что контрольные суммы уже были заранее подсчитаны

Sharp пишет:
Чтобы посчитать контрольную сумму, нужно пройтись по всему массиву. Если в файле всего одно отличие, по матожиданию достаточно пройти половину массива.

Верно

VBD пишет:
oO Просвятите, если я в чем то не прав:
В попу контрольную сумму (буэ). Туда же циклы (буээээээ!). Берем картинку А и картинку Б. Сначала сравниваем их размеры - если не совпадают - False. Затем, если они совпадают, накладываем А на другое с помощью BitBlt(.NET - DrawImageUnstretched) с битовой операцией такой, чтобы получалась разница (хоть какая-то, не помню там уже что именно, помню, что есть что-то такое :) ). Так вот, таким образом, получаем изображение, на котором отмечены только несовпадающие пиксели. То есть, если такой-то пиксель васи А равен соответствующему пикселю васи Б, то выбранная нами (не случайно) битовая операция сделает что-нибудь, обращающее цвет этого пикселя в константу. Дальше делаем SetStretchBltMode (.NET - Smoothing = Smoothing.HighQuality, или как там), и StretchBlt (.NET - DrawImage) на битмап с новыми значениями ширины 1 и высоты 1, то есть ужимаем нашего васю в один пиксель. Далее смотрим: если, допустим, наша битовая операция делал все одинаковые пиксели черными (как наложение "разница" в фотошопе), а неодинаковые - нечерными (какими-нибудь), то степень отличия картинок изменяется отличием цвета новоиспеченного пикселя от черного цвета. Ну как? Понятно, что способ не очень точен (на изображениях от 16x16 пикселей :) ), но зато, я полагаю, работает на порядки быстрее двух циклов. Остается только уточнить, есть ли хороший, годный битовый фильтр наложения для этой расты (не удержался). Смекнули?

Эта битовая операция называется XOR. В остальном - подходит как наглядное пособие по удалению гланд через жопу.

Сергей пишет:
есть подозрение, что вычисление контрольной суммы двух файлов стандартными средствами будет быстрее, чем "ручной" перебор двух массивов и пошаговое сравнение элементов массива.

Я бы на твоем месте не полагался на свою интуицию, по крайней мере пока опыт программирования не превысит 10 лет.

Ответить

Номер ответа: 14
Автор ответа:
 Сергей



ICQ: 558230345 

Вопросов: 7
Ответов: 91
 Профиль | | #14 Добавлено: 09.06.10 12:44
Я бы на твоем месте не полагался на свою интуицию, по крайней мере пока опыт программирования не превысит 10 лет.

Скромность не позволяет, но я пересилю себя. Программировать я начал еще в 1992 году. С ассемблера. 18 лет достаточно?

Ответить

Номер ответа: 15
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #15 Добавлено: 09.06.10 13:28
18 лет должно быть достаточно. Но странно, что человек, который программирует 18 лет (професионально? без перерывов?) так слабо разбирается в элементарных вещах.

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам