-
Notifications
You must be signed in to change notification settings - Fork 1
/
ImageFinder.java
151 lines (117 loc) · 4.76 KB
/
ImageFinder.java
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
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class ImageFinder {
public static void main(String[] args)
throws java.awt.AWTException, IOException
{
/*
if(args.length < 2){
System.out.println("supply wholePicture partPicture");
System.exit(1);
}
BufferedImage whole = ImageIO.read(new File(args[0]));
BufferedImage part = ImageIO.read(new File(args[1]));
ImageFinder finder = new ImageFinder(whole, part);
BufferedImage match = finder.matchImage();
ImageIO.write(match, "png", new File("match.png"));
*/
Robot robot = new Robot();
BufferedImage whole = robot.createScreenCapture(IU.getResolution());
BufferedImage part = ImageIO.read(new File("blot_158_82_80x80.png"));
ImageFinder finder = new ImageFinder(whole, part);
BufferedImage match = finder.getMatchImage();
ImageIO.write(match, "png", new File("match.png"));
}
///////////////////////////////////////////////////////////////////////////////
public RgbMat WholeMat;
public RgbMat PartMat;
public HashSet<Integer> PartRgbSet;
ImageFinder(BufferedImage wholeImage, BufferedImage partImage){
init(new RgbMat(wholeImage), new RgbMat(partImage));
}
ImageFinder(RgbMat wholeMat, RgbMat partMat){
init(wholeMat, partMat);
}
ImageFinder(RgbMat wholeMat, RgbMat partMat, HashSet<Integer> partRgbSet){
init(wholeMat, partMat, partRgbSet);
}
public void init(RgbMat wholeMat, RgbMat partMat){
init(wholeMat, partMat, IU.rgbSet(partMat));
}
public void init(RgbMat wholeMat, RgbMat partMat, HashSet<Integer> partRgbSet){
WholeMat = wholeMat;
PartMat = partMat;
PartRgbSet = partRgbSet;
}
public BufferedImage getMatchImage(){
Point offset = getOffset();
RgbMat MatchMat = new RgbMat(WholeMat);
for(int y = 0; y < PartMat.height; y++){
for(int x = 0; x < PartMat.width; x++){
MatchMat.set(offset.x + x, offset.y + y, IU.GREEN_RGB);
}
}
return MatchMat.toImage();
}
public Point getOffset(){
HashSet<Integer> partRgbSetForTopRow = IU.rgbSetForRow(PartMat, 0);
boolean matchFound = false;
for(int wsy = WholeMat.height - PartMat.height - 1; !matchFound && wsy >= 0; wsy--){
//check if this row has ANY of part's colors
HashSet<Integer> wholeRgbSetForRow = IU.rgbSetForRow(WholeMat, wsy);
HashSet<Integer> partCopy = new HashSet<Integer>(PartRgbSet);
partCopy.retainAll(wholeRgbSetForRow);
//doesn't have ANY of the colors means we can skip up quite a bit
if(partCopy.size() == 0){
wsy -= PartMat.height - 1;
continue;
}
//check if row has all of part's top row's colors
HashSet<Integer> partTopRowCopy = new HashSet<Integer>(partRgbSetForTopRow);
partTopRowCopy.retainAll(wholeRgbSetForRow);
if(partTopRowCopy.size() < partRgbSetForTopRow.size()){
continue;
}
for(int wsx = 0; !matchFound && wsx < WholeMat.width - PartMat.width; wsx++){
boolean blockDone = false;
for(int px = PartMat.width - 1; !blockDone && px >= 0; px--){
for(int py = 0; !blockDone && py < PartMat.height; py++){
int wRgb = WholeMat.get(wsx + px, wsy + py);
if(!PartRgbSet.contains(wRgb)){
blockDone = true;
wsx += px;
}
}
}
boolean offsetFine = true;
for(int px = 0; offsetFine && px < PartMat.width; px++){
for(int py = 0; offsetFine && py < PartMat.height; py++){
int wRgb = WholeMat.get(wsx + px, wsy + py);
int pRgb = PartMat.get(px, py);
if(wRgb != pRgb){
offsetFine = false;
}
}
}
if(offsetFine){
return new Point(wsx, wsy);
}
}
}
return null;
}
public boolean partAtOffset(Point offset){
for(int y = 0; y < PartMat.height; y++){
for(int x = 0; x < PartMat.width; x++){
if(PartMat.get(x, y) != WholeMat.get(x + offset.x, y + offset.y)){
return false;
}
}
}
return true;
}
}