Просмотр полной версии : Ис нова об распознавании картинок
Тема была затронута не раз. Но всё же.
Есть изображение: на странице http://l2top.ru/?voteme=1139&rating=full , требуется (как сбственно вы и догадались) распознать эту картинку.
При взгляде на это изображение срузу понятно что нет никакой защиты от распознавания - фон достаточно отличается от цвета цифр, цифры всегда имеют иди и тот же шрифт , размер и располагаются строго по центру.
Какой алгоритм здесь подойдет - распознавание по байтам или распознавание по шаблону (если кто знает четкий алгоритм скажите) ?
Начал писать код на пасе (делфи), возникла проблемка:
загружаю картинку со страницы http://l2top.ru/?voteme=1139&rating=full , сохраняю файлик как ЖПГ, открываю в mspaint, сохраняю как монохромный, плучается здорово !
Попытался реализовать аналогичное на делфи - не катит, получается все равно 24 бита:
function JPEG2BMP(const JPGFile, BMPFile: string): boolean;
var
JPG: TJPEGImage;
BMP: TBitmap;
begin
JPG:= TJPEGImage.Create;
BMP:= TBitmap.Create;
try
JPG.LoadFromFile(JPGFile);
BMP.PixelFormat:= pf1bit;
BMP.Assign(JPG);
BMP.SaveToFile(BMPFile);
finally
FreeAndNil(JPG);
FreeAndNil(BMP);
Result:= FileExists(BMPFile);
end;
end;
Наверно не в той ветке создал эту тему. С формулируй вопрос правильней!
тут достаточно определить цвет цифр, а так цифры всегда стоят на одних и тех же местах просто берем точку с нужной координатой. но тут возможно наложении на нее шума, поэтому берем область одной из цифр размерами 5х5 и находим тот цвет который встречается чаще - это и будет искомый. делаем с этого всего битовую матрицу - 1-пиксель принадлежит цифре, 0 - не принадлежит. сравниваем количество точек при совмещении. все.
Может быть проще сравнивать по заранее готовому шаблону ? Именно так я и хочу сделать, т.е. у меня имеются 10 файлов с готовыми шаблонами цифр - от 0 до 9, такого же размера как и на примере картинки и четко черно-белого цвета, далее просто дело прямых рук написания кода для сравнения, с этим у меня проблем, думаю не будет.
Но вот проблемка в преобразовании цветной картинки JPeG в черно-белую BMP (код см. выше), не могу понять почему не работат, думаю что компонент делфи как то кривовато работает, может есть другой способ?
Вобщем с изобрадением я разобрался, вот код:
function setBWColor(c: TColor): TColor;
begin
if c > (255*255*255)/2
then c := clWhite
else c := clBlack;
Result := c;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
h, w: Integer;
begin
for w := 0 to Image1.Width-1 do
for h := 0 to Image1.Height-1 do
Image1.Canvas.Pixels[w,h] := setBWColor(Image1.Canvas.Pixels[w,h]);
end;
В результате из BMP-шной картинки получается монохромное изображение. Теперь задача его раскодировать
Теперь задача его раскодировать
))))))))))))
непредвиденное обстоятельство, да?))
Ну, вобщем приложение готово, работает по шаблону, всё очень просто
вот код
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, jpeg, ExtDlgs;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
OpenPictureDialog1: TOpenPictureDialog;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TMas = array[1..210, 1..65] of Boolean;
var
Form1: TForm1;
Mas: TMas;
dir: String;
implementation
{$R *.dfm}
function JPEG2BMP(const JPGFile, BMPFile: string): boolean;
// Ôóíêöèÿ äëÿ êîíâåðòèðîâàíèÿ JPEG ôàéëà â <BMP>
// JPGFile - èìÿ îòêðûâàåìîãî ôàéëà
// BMPFile - èìÿ <ñîõðàíÿåìîãî> ôàéëà
var
JPG: TJPEGImage;
BMP: TBitmap;
begin
JPG := TJPEGImage.Create;
BMP := TBitmap.Create;
try
JPG.LoadFromFile(JPGFile);
BMP.PixelFormat:= pf1bit;
BMP.Assign(JPG);
BMP.SaveToFile(BMPFile);
finally
FreeAndNil(JPG);
FreeAndNil(BMP);
Result := FileExists(BMPFile);
end;
end;
function setBWColor(c: TColor): TColor;
begin
if c > (255*255*255)/2
then c := clWhite
else c := clBlack;
Result := c;
end;
function encodeImg(Mas: TMas): String;
type
Tfiles = array[0..9] of String;
var
f: Tfiles;
i, j, k: Integer;
shablon: array[1..32, 1..12] of Boolean;
BMP: TBitmap;
max, equal: Integer;
temp, st: String;
begin
for i := 0 to 9 do
f[i] := dir + '/shablon/' + IntToStr(i) + '.bmp';
BMP := TBitmap.Create;
st := '';
max := 0;
// 1 öèôðà
for k := 0 to 9 do
begin
BMP.LoadFromFile(f[k]);
for i := 1 to 32 do
for j := 1 to 12 do
if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
then shablon[i,j] := true
else shablon[i,j] := false;
equal := 0;
for i := 1 to 32 do
for j := 1 to 12 do
begin
if shablon[i,j] = Mas[i+27,j+16] then equal := equal + 1;
end;
if (equal > max) then
begin
max := equal;
temp := IntToStr(k);
end;
end;
st := st + temp;
max := 0;
// 2 öèôðà
for k := 0 to 9 do
begin
BMP.LoadFromFile(f[k]);
for i := 1 to 32 do
for j := 1 to 12 do
if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
then shablon[i,j] := true
else shablon[i,j] := false;
equal := 0;
for i := 1 to 32 do
for j := 1 to 12 do
begin
if shablon[i,j] = Mas[i+54,j+16] then equal := equal + 1;
end;
if (equal > max) then
begin
max := equal;
temp := IntToStr(k);
end;
end;
st := st + temp;
max := 0;
// 3 öèôðà
for k := 0 to 9 do
begin
BMP.LoadFromFile(f[k]);
for i := 1 to 32 do
for j := 1 to 12 do
if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
then shablon[i,j] := true
else shablon[i,j] := false;
equal := 0;
for i := 1 to 32 do
for j := 1 to 12 do
begin
if shablon[i,j] = Mas[i+81,j+16] then equal := equal + 1;
end;
if (equal > max) then
begin
max := equal;
temp := IntToStr(k);
end;
end;
st := st + temp;
max := 0;
// 4 öèôðà
for k := 0 to 9 do
begin
BMP.LoadFromFile(f[k]);
for i := 1 to 32 do
for j := 1 to 12 do
if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
then shablon[i,j] := true
else shablon[i,j] := false;
equal := 0;
for i := 1 to 32 do
for j := 1 to 12 do
begin
if shablon[i,j] = Mas[i+108,j+16] then equal := equal + 1;
end;
if (equal > max) then
begin
max := equal;
temp := IntToStr(k);
end;
end;
st := st + temp;
max := 0;
// 5 öèôðà
for k := 0 to 9 do
begin
BMP.LoadFromFile(f[k]);
for i := 1 to 32 do
for j := 1 to 12 do
if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
then shablon[i,j] := true
else shablon[i,j] := false;
equal := 0;
for i := 1 to 32 do
for j := 1 to 12 do
begin
if shablon[i,j] = Mas[i+135,j+16] then equal := equal + 1;
end;
if (equal > max) then
begin
max := equal;
temp := IntToStr(k);
end;
end;
st := st + temp;
max := 0;
// 6 öèôðà
for k := 0 to 9 do
begin
BMP.LoadFromFile(f[k]);
for i := 1 to 32 do
for j := 1 to 12 do
if (BMP.Canvas.Pixels[i-1,j-1] = clWhite)
then shablon[i,j] := true
else shablon[i,j] := false;
equal := 0;
for i := 1 to 32 do
for j := 1 to 12 do
begin
if shablon[i,j] = Mas[i+162,j+16] then equal := equal + 1;
end;
if (equal > max) then
begin
max := equal;
temp := IntToStr(k);
end;
end;
st := st + temp;
Result := st;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
h, w: Integer;
Mas: TMas;
begin
OpenPictureDialog1.Execute;
JPEG2BMP(OpenPictureDialog1.FileName, dir+'/temp/temp.bmp');
Image1.Picture.LoadFromFile(dir+'temp/temp.bmp');
for w := 0 to Image1.Width-1 do
for h := 0 to Image1.Height-1 do
begin
Image1.Canvas.Pixels[w,h] := setBWColor(Image1.Canvas.Pixels[w,h]);
if (Image1.Canvas.Pixels[w,h] = clWhite)
then Mas[w+1, h+1] := true //áåëûé
else Mas[w+1, h+1] := false; //÷åðíûé
end;
Edit1.Text := encodeImg(Mas);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
dir := ExtractFilePath(ParamStr(0));
end;
end.
p.s. работает только для картинки по адресу http://l2top.ru/?voteme=1139&rating=full , но на этой основе можно забадяжить своё :)
))))))))))))
непредвиденное обстоятельство, да?))
Уже нет :)
А такая красивая функция encodeImg(), аж прямо ужас
>>Может быть проще сравнивать по заранее готовому шаблону ?
как вы будете сравнивать с шаблоном если на изображении "мусор"?
Zadoxlik
19.01.2007, 22:38
тут достаточно определить цвет цифр, а так цифры всегда стоят на одних и тех же местах просто берем точку с нужной координатой. но тут возможно наложении на нее шума, поэтому берем область одной из цифр размерами 5х5 и находим тот цвет который встречается чаще - это и будет искомый. делаем с этого всего битовую матрицу - 1-пиксель принадлежит цифре, 0 - не принадлежит. сравниваем количество точек при совмещении. все.
я так капчу на твоем хомяке сломал :D
у меня даже проще, без шума и координатных растяжений\поворотов было :)
Zadoxlik
19.01.2007, 22:43
Точно :dddd
А такая красивая функция encodeImg(), аж прямо ужас
Выше говорилось что это функция специфична только для данной картинки, поэтому прошу строго не судить о названии функций :)
сам шум на этой картинке (http://l2top.ru - выберите сайт нажмите кнопку "мой выбор" чтобы увидеть картинку) представлен в другом цвете, именно поэтому я преобразовываю картинку в монохромный рисунок , что позводяет убрать шум .
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot