Skip to content

Commit e03ad0b

Browse files
committed
fix: resolve conversation
1 parent be89641 commit e03ad0b

File tree

8 files changed

+97
-9
lines changed

8 files changed

+97
-9
lines changed

src/geometry/__tests__/getPerspectiveWarp.test.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Image } from '../../Image.js';
2-
import getPerspectiveWarp, { order4Points } from '../getPerspectiveWarp.js';
2+
import { getPerspectiveWarp, order4Points } from '../getPerspectiveWarp.js';
33

44
describe('4 points sorting', () => {
55
test('basic sorting test', () => {
@@ -97,7 +97,7 @@ describe('warping tests', () => {
9797

9898
describe('openCV comparison', () => {
9999
test('nearest interpolation plants', () => {
100-
const image = testUtils.load('various/plants.png');
100+
const image = testUtils.load('opencv/plants.png');
101101
const openCvResult = testUtils.load(
102102
'opencv/test_perspective_warp_plants_nearest.png',
103103
);
@@ -134,7 +134,7 @@ describe('openCV comparison', () => {
134134
});
135135

136136
test('nearest interpolation card', () => {
137-
const image = testUtils.load('various/card.png');
137+
const image = testUtils.load('opencv/card.png');
138138
const openCvResult = testUtils.load(
139139
'opencv/test_perspective_warp_card_nearest.png',
140140
);
@@ -171,7 +171,7 @@ describe('openCV comparison', () => {
171171
expect(croppedPiece).toEqual(croppedPieceOpenCv);
172172
});
173173
test('nearest interpolation poker card', () => {
174-
const image = testUtils.load('various/poker_cards.png');
174+
const image = testUtils.load('opencv/poker_cards.png');
175175
const openCvResult = testUtils.load(
176176
'opencv/test_perspective_warp_poker_cards_nearest.png',
177177
);
@@ -215,4 +215,17 @@ describe('error testing', () => {
215215
'The array pts must have four elements, which are the four corners. Currently, pts have 1 elements',
216216
);
217217
});
218+
test('should throw if either only width or only height are defined', () => {
219+
expect(() => {
220+
getPerspectiveWarp(
221+
[
222+
{ column: 1, row: 1 },
223+
{ column: 2, row: 1 },
224+
{ column: 2, row: 2 },
225+
{ column: 1, row: 2 },
226+
],
227+
{ width: 10 },
228+
);
229+
}).toThrow('Height is not defined');
230+
});
218231
});

src/geometry/getPerspectiveWarp.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { Matrix, SingularValueDecomposition } from 'ml-matrix';
22

33
import type { Point } from '../utils/geometry/points.js';
44

5+
/**
6+
* Options for getPerspectiveWarp function.
7+
*/
58
interface GetPerspectiveWarpOptions {
69
/**
710
* The horizontal dimension (in pixels) of the final rectified rectangular image.
@@ -30,7 +33,7 @@ type GetPerspectiveWarpData = Required<GetPerspectiveWarpOptions> & {
3033
* @param options - PerspectiveWarpOptions
3134
* @returns - Matrix from 4 points.
3235
*/
33-
export default function getPerspectiveWarp(
36+
export function getPerspectiveWarp(
3437
pts: Point[],
3538
options: GetPerspectiveWarpOptions = {},
3639
): GetPerspectiveWarpData {
@@ -47,13 +50,15 @@ export default function getPerspectiveWarp(
4750
if (height && width) {
4851
widthRect = width;
4952
heightRect = height;
50-
} else {
53+
} else if (!height && !width) {
5154
widthRect = Math.ceil(
5255
Math.max(distance2Points(tl, tr), distance2Points(bl, br)),
5356
);
5457
heightRect = Math.ceil(
5558
Math.max(distance2Points(tl, bl), distance2Points(tr, br)),
5659
);
60+
} else {
61+
throw new Error(`${width ? 'Height' : 'Width'} is not defined.`);
5762
}
5863

5964
const [x1, y1] = [0, 0];

src/geometry/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export * from './resize.js';
22
export * from './rotate.js';
33
export * from './transform.js';
44
export * from './transformRotate.js';
5+
export * from './getPerspectiveWarp.js';
56
export type { Point } from '../utils/geometry/points.js';

test/TestImagePath.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ export type TestImagePath =
6666
| 'morphology/alphabetCannyEdge.png'
6767
| 'morphology/grayscaleCannyEdge.png'
6868
| 'morphology/grayscaleClearBorder.png'
69+
| 'opencv/card.png'
70+
| 'opencv/plants.png'
71+
| 'opencv/poker_cards.png'
6972
| 'opencv/test.png'
7073
| 'opencv/testAffineTransform.png'
7174
| 'opencv/testAntiClockwiseRot90.png'
@@ -98,10 +101,7 @@ export type TestImagePath =
98101
| 'ssim/ssim-original.png'
99102
| 'ssim/ssim-saltPepper.png'
100103
| 'various/alphabet.jpg'
101-
| 'various/card.png'
102104
| 'various/grayscale_by_zimmyrose.png'
103-
| 'various/plants.png'
104-
| 'various/poker_cards.png'
105105
| 'various/screws.png'
106106
| 'various/sudoku.jpg'
107107
| 'various/without-metadata.jpg';
File renamed without changes.

test/img/opencv/generate.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,72 @@ def writeImg(name, img):
9191
kernelY = np.float32([[0.4, 0.5, 0.6, -0.3, -0.4]])
9292
dst = cv.sepFilter2D(img, ddepth=-1, kernelX=kernelX, kernelY=kernelY, borderType=cv.BORDER_REFLECT)
9393
writeImg('testConvolution.png', dst)
94+
95+
96+
# Image perspective warp
97+
98+
img = cv.imread(path.join(dirname,'poker_cards.png'))
99+
100+
# Define source points (4 corners of the document in the image)
101+
# These points should be in clockwise or counter-clockwise order
102+
src_points = np.array([
103+
[660, 290],
104+
[970, 290],
105+
[1100,660],
106+
[680,660],
107+
], dtype=np.float32)
108+
# Define destination points (rectangle)
109+
width, height = 420,393
110+
dst_points = np.array([
111+
[0, 0], # top-left
112+
[width-1, 0], # top-right
113+
[width-1, height-1], # bottom-right
114+
[0, height-1] # bottom-left
115+
], dtype=np.float32)
116+
M = cv.getPerspectiveTransform(src_points,dst_points)
117+
warped = cv.warpPerspective(img, M, (width, height),flags=cv.INTER_NEAREST)
118+
writeImg('test_perspective_warp_poker_cards_nearest.png',warped)
119+
120+
121+
122+
img = cv.imread(path.join(dirname,'plants.png'))
123+
src_points = np.array([
124+
[166.5, 195],
125+
[858.5,9],
126+
[911.5,786],
127+
[154.5, 611],
128+
], dtype=np.float32)
129+
width, height = 1080,810
130+
dst_points = np.array([
131+
[0, 0], # top-left
132+
[width-1, 0], # top-right
133+
[width-1, height-1], # bottom-right
134+
[0, height-1] # bottom-left
135+
], dtype=np.float32)
136+
M = cv.getPerspectiveTransform(src_points,dst_points)
137+
warped = cv.warpPerspective(img, M, (width, height),flags=cv.INTER_NEAREST
138+
)
139+
writeImg('test_perspective_warp_plants_nearest.png',warped)
140+
141+
img = cv.imread(path.join(dirname,'card.png'))
142+
143+
# Define source points (4 corners of the document in the image)
144+
# These points should be in clockwise or counter-clockwise order
145+
src_points = np.array([
146+
[55, 140],
147+
[680,38],
148+
[840, 340],
149+
[145, 460],
150+
], dtype=np.float32)
151+
width, height =700,400
152+
dst_points = np.array([
153+
[0, 0], # top-left
154+
[width-1, 0], # top-right
155+
[width-1, height-1], # bottom-right
156+
[0, height-1] # bottom-left
157+
], dtype=np.float32)
158+
159+
M = cv.getPerspectiveTransform(src_points,dst_points)
160+
warped = cv.warpPerspective(img, M, (width, height),flags=cv.INTER_NEAREST
161+
)
162+
writeImg('test_perspective_warp_card_nearest.png',warped)
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)