打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
如何改进这段关于图像的查找的代码
在学图像编程,书都翻烂了,也没找到好的处理方法...
路过的大虾帮看一下,代码不多,我的代码已经可以正常查找,但是当遇到图像有一点点差异就不行了,我想加入容错机制,
但怎么搞,都解决不了..



需求是这样:
.有一个大图image1,有很多小图在路径Edit1.txt,小图存在于大图中不同的地方,要找出不同的小图在大图中的位置,然后标识出这个小图的名称出来.

要达到的效果:
如果小图有一点像索点的差异,需要可以容错的找出来.
我试过了采用像素点数的方法,但要一个常数,参数值得出的结果也不精准.

可不可以采用一个区域宽度内的相似度算法呢?把相似度最好的找出来.
但不知如何下手,或是有没有别的方法呢?



Delphi/Pascal code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//代码可以运行和测试,可以在大图里截几个小图试一下,用简单的黑白图片测试即可(截那个图里的几个小图存到一个路径里做模
//版,Edit1的值指向那个路径,Image1加载大图),24位的bmp格式.
unit Main;
interface
uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, ExtCtrls, StdCtrls, ExtDlgs, IdGlobal;
const
    PixelCountMax = 32768;
type
    pRGBTripleArray = ^TRGBTripleArray;
    TRGBTripleArray = array[0..PixelCountMax - 1of TRGBTriple;
type
    TMainForm = class(TForm)
        Image1: TImage;
        Image2: TImage;
        Memo1: TMemo;
        Button1: TButton;
        OpenPictureDialog1: TOpenPictureDialog;
        OpenPictureDialog2: TOpenPictureDialog;
        Label1: TLabel;
        Memo2: TMemo;
        Edit1: TEdit;
        Button4: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        function BmpCmpEx(bmpBig, bmp: TBitmap; x, y: integer; nV: byte): boolean//图片对比
        function BmpFindEx(bmpBig, bmp: TBitmap; x1, y1, x2, y2: integer; nV: byte; Txt: string): Boolean;
    private
        { Private declarations }
    public
        { Public declarations }
    end;
var
    MainForm: TMainForm;
    //L, T, Lx: Integer; //已找到的子图的x和Y值 ,也就是左边和上边
    bmpFindX, bmpFindY: Integer//第二种方法找到的点
    TxtAry: array of string;
    eight: array[1..81..8of TLabel;
implementation
uses StrUtils;
{$R *.dfm}
//初始化
procedure TMainForm.FormCreate(Sender: TObject);
begin
    DoubleBuffered := True;
    Image1.Picture.Bitmap.PixelFormat := pf24bit;
    Image2.Picture.Bitmap.PixelFormat := pf24bit;
end;
// 在大图里对比小图
function TMainForm.BmpCmpEx(bmpBig, bmp: TBitmap; x, y: integer; nV: byte): boolean;
var
    i, j: integer;
    row1, row2: pRGBTripleArray;
    p1, p2: TRGBTriple;
    pLow, pHigh: TRGBTriple;
begin
    result := true;
    //扫描整个小图
    for j := 0 to bmp.Height - 1 do
    begin
        row1 := bmpBig.ScanLine[y + j]; //大图
        row2 := bmp.ScanLine[j]; //小图
        for i := 0 to bmp.Width - 1 do
        begin
            p1 := row1[x + i];
            p2 := row2[i];
            if not ((p1.rgbtRed = p2.rgbtRed) and
                (p1.rgbtGreen = p2.rgbtGreen) and
                (p1.rgbtBlue = p2.rgbtBlue)) then
            begin
                result := false;
                exit; //不同则退出
            end
        end;
    end;
end;
// 在大图里的(x1,y1)和(x2,y2)中找出小图来?
// 当返回true时,以下变量存放找到的位置
//    bmpFindX:integer;
//    bmpFindY:integer; 
function TMainForm.BmpFindEx(bmpBig, bmp: TBitmap; x1, y1, x2, y2: integer; nV: byte; Txt: string): Boolean;
var
    x, y: integer;
begin
    if x1 + y1 + x2 + y2 = 0 then
    begin
        x1 := 0;
        y1 := 0;
        x2 := bmpBig.Width - 1;
        y2 := bmpBig.Height - 1;
    end;
    for y := y1 to y2 - 1 do //循环大图的行
    begin
        if bmp.Height > y2 - y then //高度不够,失败了
            break;
        for x := x1 to x2 - 1 do //循环大图的列
        begin
            if (bmp.Width > x2 - x) then //宽度不够,本行完成检查了
                break;
            begin
                Application.ProcessMessages;
                if BmpCmpEx(bmpBig, bmp, x, y, nV) then//在每一个大图的点上,对比小图,
                begin
                    TxtAry[x] := txt; //找到后,把匹配的小图的位置记录到对应的数组中//数组长度本来就是以图片长度为准的
                    result := true;
                    bmpFindX := x;
                    bmpFindY := y;
                end;
            end// end if
        end// end for x
    end// end for y
    result := false// 到这里就是失败
end;
procedure TMainForm.Button1Click(Sender: TObject);
var
    i, j, k: Integer;
    LibDir, LibName: string//小图的文件位置和名称
    LibStr: TStringList; //把图片长度变成每个点,把检测到图片名字填上去
begin
    try
        LibDir := edit1.Text; //读取小图模版文件列表
        LibStr := TStringList.Create;
        LibStr.LoadFromFile(LibDir + 'Lib.txt');
        SetLength(TxtAry, 0);
        SetLength(TxtAry, Image1.Picture.Bitmap.Width); // 数组长度等于图片宽度
        for i := 0 to LibStr.Count - 1 do //循环所有的小图模版图片
        begin
            Application.ProcessMessages;
            LibName := LibDir + LibStr.Strings[i] + '.bmp';
            if not FileExists(LibName) then
                Continue;
            Image2.Picture.LoadFromFile(LibName); // 加载小图模版图片
            //第二种找图方法
            if BmpFindEx(Image1.Picture.Bitmap, Image2.Picture.Bitmap, 00, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height, 5, LibStr.Strings[i]) then //LibStr.Strings[i]就是小图的文件名
            begin
                //Memo2.Lines.Add(IntToStr(bmpFindX)+','+IntToStr(bmpFindY)+':'+LibStr.Strings[i]);
            end;
        end;
    finally
        LibStr.Free;
    end;
    Memo1.Lines.SaveToFile('C:\log.txt');
end;
end.
更多 0 分享到:

忽然想到可以做二维的相关,最大值就是最相似的点。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
EXCEL:一个工作薄中多个工作表合并代码
基于KL26Z的串行TFT屏图像显示
Inno Setup详细教程
积分图的概念、计算及代码
几种经典的二值化方法及其vb.net实现
delphi 图像 16进制 转换
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服