Skip to content

Commit 46a35c8

Browse files
committed
Improved debug output
1 parent aee6adf commit 46a35c8

File tree

1 file changed

+75
-20
lines changed

1 file changed

+75
-20
lines changed

lib/provider/opencv/template-matching-finder.class.ts

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as cv from "opencv4nodejs";
2+
import * as path from "path";
23
import { Image } from "../../image.class";
34
import { MatchRequest } from "../../match-request.class";
45
import { MatchResult } from "../../match-result.class";
@@ -34,21 +35,24 @@ export class TemplateMatchingFinder implements FinderInterface {
3435
private static async scaleAndMatchNeedle(
3536
haystack: cv.Mat,
3637
needle: cv.Mat,
38+
debug: boolean = false
3739
): Promise<MatchResult> {
3840
const scaledNeedle = await TemplateMatchingFinder.scale(
3941
needle,
4042
TemplateMatchingFinder.scaleStep,
4143
);
4244
const matchResult = await TemplateMatchingFinder.match(haystack, scaledNeedle);
43-
// cv.imwriteAsync(`${"scaled_needle.png"}`, scaledNeedle);
44-
console.log(`Scaled needle: ${matchResult.confidence}`);
45+
if (debug) {
46+
this.debugImage(scaledNeedle, "scaled_needle.png");
47+
console.log(`Scaled needle: ${matchResult.confidence}`);
48+
}
4549
return new MatchResult(
4650
matchResult.confidence,
4751
new Region(
4852
matchResult.location.left,
4953
matchResult.location.top,
50-
scaledNeedle.cols,
51-
scaledNeedle.rows,
54+
needle.cols,
55+
needle.rows,
5256
),
5357
);
5458
}
@@ -63,14 +67,17 @@ export class TemplateMatchingFinder implements FinderInterface {
6367
private static async scaleAndMatchHaystack(
6468
haystack: cv.Mat,
6569
needle: cv.Mat,
70+
debug: boolean = false
6671
): Promise<MatchResult> {
6772
const scaledHaystack = await TemplateMatchingFinder.scale(
6873
haystack,
6974
TemplateMatchingFinder.scaleStep,
7075
);
7176
const matchResult = await TemplateMatchingFinder.match(scaledHaystack, needle);
72-
// cv.imwriteAsync(`${"scaled_haystack.png"}`, scaledHaystack);
73-
console.log(`Scaled haystack: ${matchResult.confidence}`);
77+
if (debug) {
78+
this.debugImage(scaledHaystack, "scaled_haystack.png");
79+
console.log(`Scaled haystack: ${matchResult.confidence}`);
80+
}
7481
return new MatchResult(
7582
matchResult.confidence,
7683
new Region(
@@ -82,31 +89,79 @@ export class TemplateMatchingFinder implements FinderInterface {
8289
);
8390
}
8491

92+
private static async debugImage(image: cv.Mat, filename: string, suffix?: string) {
93+
const parsedPath = path.parse(filename);
94+
let fullFilename = parsedPath.name;
95+
if (suffix) {
96+
fullFilename = fullFilename + "_" + suffix;
97+
}
98+
fullFilename += parsedPath.ext;
99+
const fullPath = path.join(parsedPath.dir, fullFilename);
100+
cv.imwriteAsync(fullPath, image);
101+
}
102+
103+
private static async debugResult(image: cv.Mat, result: MatchResult, filename: string, suffix?: string) {
104+
const roiRect = new cv.Rect(
105+
result.location.left,
106+
result.location.top,
107+
result.location.width,
108+
result.location.height);
109+
this.debugImage(image.getRegion(roiRect), filename, suffix);
110+
}
111+
85112
constructor() {
86113
}
87114

88-
public async findMatches(matchRequest: MatchRequest): Promise<MatchResult[]> {
89-
let needle = await this.loadImage(matchRequest.pathToNeedle);
115+
public async findMatches(matchRequest: MatchRequest, debug: boolean = false): Promise<MatchResult[]> {
116+
const needle = await this.loadImage(matchRequest.pathToNeedle);
90117
if (needle.empty) {
91118
throw new Error(
92119
`Failed to load ${matchRequest.pathToNeedle}, got empty image.`,
93120
);
94121
}
95-
let haystack = await this.loadHaystack(matchRequest);
122+
const haystack = await this.loadHaystack(matchRequest);
96123

97-
if (matchRequest.confidence < 0.99) {
98-
needle = await this.rgbToGrayScale(needle);
99-
haystack = await this.rgbToGrayScale(haystack);
124+
if (debug) {
125+
TemplateMatchingFinder.debugImage(needle, "input_needle.png");
126+
TemplateMatchingFinder.debugImage(haystack, "input_haystack.png");
100127
}
101-
// cv.imwriteAsync(`${"input_needle.png"}`, needle);
102-
// cv.imwriteAsync(`${"input_haystack.png"}`, haystack);
103128

104129
const matchResults = [];
105-
matchResults.push(await TemplateMatchingFinder.match(haystack, needle));
106-
if (matchRequest.searchMultipleScales) {
107-
matchResults.push(await TemplateMatchingFinder.scaleAndMatchHaystack(haystack, needle));
108-
matchResults.push(await TemplateMatchingFinder.scaleAndMatchNeedle(haystack, needle));
130+
const unscaledResult = await TemplateMatchingFinder.match(haystack, needle);
131+
if (debug) {
132+
console.log(`Unscaled result: ${unscaledResult.confidence}`);
133+
TemplateMatchingFinder.debugResult(
134+
haystack,
135+
unscaledResult,
136+
matchRequest.pathToNeedle,
137+
"unscaled_result");
138+
}
139+
if (
140+
matchRequest.searchMultipleScales &&
141+
unscaledResult.confidence >= Math.max(matchRequest.confidence - 0.1, 0.6)
142+
) {
143+
const scaledHaystack = await TemplateMatchingFinder.scaleAndMatchHaystack(haystack, needle, debug);
144+
if (debug) {
145+
TemplateMatchingFinder.debugResult(
146+
haystack,
147+
scaledHaystack,
148+
matchRequest.pathToNeedle,
149+
"scaled_haystack_result"
150+
);
151+
}
152+
matchResults.push(scaledHaystack);
153+
const scaledNeedle = await TemplateMatchingFinder.scaleAndMatchNeedle(haystack, needle, debug);
154+
if (debug) {
155+
TemplateMatchingFinder.debugResult(
156+
haystack,
157+
scaledNeedle,
158+
matchRequest.pathToNeedle,
159+
"scaled_needle_result"
160+
);
161+
}
162+
matchResults.push(scaledNeedle);
109163
}
164+
matchResults.push(unscaledResult);
110165

111166
// Compensate pixel density
112167
matchResults.forEach(matchResult => {
@@ -121,8 +176,8 @@ export class TemplateMatchingFinder implements FinderInterface {
121176
);
122177
}
123178

124-
public async findMatch(matchRequest: MatchRequest): Promise<MatchResult> {
125-
const matches = await this.findMatches(matchRequest);
179+
public async findMatch(matchRequest: MatchRequest, debug: boolean = false): Promise<MatchResult> {
180+
const matches = await this.findMatches(matchRequest, debug);
126181
if (matches.length === 0) {
127182
throw new Error(
128183
`Unable to locate ${matchRequest.pathToNeedle}, no match!`,

0 commit comments

Comments
 (0)