-
Здравствуйте, уважаемые! Я пишу алгоритм сравнения двух изображений, а именно фотографий. Сравнивать нужно попиксельно, и, выводить в процентах. Если они похожи более чем, допустим, 60%, программа выполняет какое-то действие. Надо их, как я понимаю поместить изображения в байтовые массивы и затем сравнить их. Вот такой напиал код, но, как понимаю что-то в нем не так. При запуске и нажатии на кнопку вылетает Access Violation. Что я делаю не так? Помогите, пожалуйста. Заранее спасибо!
var BytesPerPixel, PixelsPerByte: LongInt; s, f: TmemoryStream; b1, b2: TBitmap; c1, c2: PByte; x, y, i, different: Integer; // Counter for different pixels begin s:=TmemoryStream.create; f:=TmemoryStream.create; s.LoadFromFile('C:\1.bmp'); f.LoadFromFile('C:\2.bmp'); b1 := s.Memory; b2 := f.Memory; Assert(b1.PixelFormat = b2.PixelFormat); // they have to be equal different := 0; for y := 0 to b1.Height - 1 do begin c1 := b1.Scanline[y]; c2 := b2.Scanline[y]; for x := 0 to b1.Width - 1 do for i := 0 to BytesPerPixel - 1 do // 1, to 4, dep. on pixelformat begin Inc(different, Integer(c1^ <> c2^)); Inc(c1); Inc(c2); end; end; end;
-
Какой-то ты ужас делаешь.. TBitmap создай 2 штуки. Без всякой MemoryStream. Они как 2-мерный массив работают. Двумя циклами проходишься. При этом сравни размеры изображений. Они должны быть равны.
-
> Я пишу алгоритм сравнения двух изображений,
Так "пишу" или "изобретаю" ? Это разные вещи.
-
b1 := s.Memory; b2 := f.Memory; Вот это ты делаешь совсем не так
-
Удалено модератором
-
> алгоритм сравнения двух изображений
да еще с процентной похожестью - очень сложная вещь. даже у гугла кривовато получилось.
> а именно фотографий
берем одну фотографию. и берем эту же фотографию, но повернутую на 180. на сколько они похожи и что даст попиксельное сравнение?
-
Да даже не на 180, а на любое не кратное 360 =))) Может по условию без масштабирования и поворота. Теперь по существу. TBitmap - это класс. b1 и b2 - это указатели на объекты класса TBitmap. b1:=s.Memory; - даже не соображу что получится при таком финте, но точно что абсолютно не то что нужно. Вот так: b1:=TBitmap.Create; b1.LoadFromFile('...'); Это вот: Assert(b1.PixelFormat = b2.PixelFormat); вообще ни о чём. Приводишь оба к тому который нужен, 24 или 32: b1.PixelFormat:=pf24bit; b2.PixelFormat:=pf24bit; > похожи более чем, допустим, 60%Что значит "похожи на X процентов"? Дайте точное определение.
-
> похожи на X процентов
фотография девушки. одна и та же. но на одном она в красном пальто, на другом - в зеленом. пальто занимает 41% площади снимка. попиксельное сравнение выдаст 59%, что неправда...
я бы сначала разбил изображение на более крупные "пиксели", например, 10х10.с переводом в чб, (не градации серого, а именно 2 бита). В итоге вышло бы нечто страшно-силуэтное, но 100%-ое совпадение этих двух страшных фоток теоретически дало бы 60% совпадения оригинала.
-
те опираться только на "яркость" пиксела? имхо не айс...
-
уж лучше тогда смотреть на разность RGB составляющих пикселов изображений... те if Abs(R1-R2) >=пороговое значение для различия or
Abs(G1-G2) >=пороговое значение для различия or
Abs(B1-B2) >=пороговое значение для различия
then пикселы различны...
-
мда, никрофилия(
-
яркость не айс, но на первых шагах самое простое решение. возможно, для специфичных картинок даже идеальное.
|