Skip to content

Commit cfd9575

Browse files
committed
Implement unwarping
1 parent d508f75 commit cfd9575

File tree

8 files changed

+42
-20
lines changed

8 files changed

+42
-20
lines changed

dist/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bundle.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/hello.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/hello.wasm

83 KB
Binary file not shown.

dist/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<div class="container">
1414
<div cass="row">
1515
<div class="col-md-12">
16-
<div class="version pull-right">(version: 0.0.15)</div>
16+
<div class="version pull-right">(version: 0.0.16)</div>
1717
</div>
1818
</div>
1919
<div cass="row">

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "emscripten-opencv",
3-
"version": "0.0.15",
3+
"version": "0.0.16",
44
"description": "Web app calling into C++ WebAssembly code that uses OpenCV",
55
"scripts": {
66
"eslint": "eslint .",

src/hello.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@ vector<Point> findCorners(const vector<Point> &contour) {
4949
return corners;
5050
}
5151

52+
void applyWarpPerspective(const Mat &matIn, Mat &matOut, const vector<Point> &corners) {
53+
auto widthTop = distance(corners[0], corners[1]);
54+
auto widthBottom = distance(corners[2], corners[3]);
55+
auto heightLeft = distance(corners[0], corners[3]);
56+
auto heightRight = distance(corners[1], corners[2]);
57+
auto unwarpedSize = Size(max(widthTop, widthBottom), max(heightLeft, heightRight));
58+
auto unwarpedCorners = vector<Point2f>(4);
59+
unwarpedCorners[0] = Point2f(0, 0);
60+
unwarpedCorners[1] = Point2f(unwarpedSize.width, 0);
61+
unwarpedCorners[2] = Point2f(unwarpedSize.width, unwarpedSize.height);
62+
unwarpedCorners[3] = Point2f(0, unwarpedSize.height);
63+
auto warpedCorners = vector<Point2f>(4);
64+
warpedCorners[0] = Point2f(corners[0].x, corners[0].y);
65+
warpedCorners[1] = Point2f(corners[1].x, corners[1].y);
66+
warpedCorners[2] = Point2f(corners[2].x, corners[2].y);
67+
warpedCorners[3] = Point2f(corners[3].x, corners[3].y);
68+
auto transform = getPerspectiveTransform(warpedCorners.data(), unwarpedCorners.data());
69+
warpPerspective(matIn, matOut, transform, unwarpedSize);
70+
}
71+
5272
#ifdef __cplusplus
5373
extern "C" {
5474
#endif
@@ -94,23 +114,25 @@ int *processImage(uchar *array, int width, int height) {
94114
auto bb = boundingRect(contours[indexMaxArea]);
95115

96116
auto corners = findCorners(contours[indexMaxArea]);
117+
Mat matUnwarped;
118+
applyWarpPerspective(matNormalised, matUnwarped, corners);
97119

98120
int return_image_1_width = matNormalised.cols;
99121
int return_image_1_height = matNormalised.rows;
100122
int return_image_1_channels = matNormalised.channels();
101123
int return_image_1_size = return_image_1_width * return_image_1_height * return_image_1_channels;
102124

103-
int return_image_2_width = matBinary.cols;
104-
int return_image_2_height = matBinary.rows;
105-
int return_image_2_channels = matBinary.channels();
125+
int return_image_2_width = matUnwarped.cols;
126+
int return_image_2_height = matUnwarped.rows;
127+
int return_image_2_channels = matUnwarped.channels();
106128
int return_image_2_size = return_image_2_width * return_image_2_height * return_image_2_channels;
107129

108130
int return_data_size = 20 * sizeof(int) + return_image_1_size + return_image_2_size;
109131
int *return_data = reinterpret_cast<int*>(malloc(return_data_size));
110132
uchar *return_image_1_addr = reinterpret_cast<uchar*>(&return_data[20]);
111133
uchar *return_image_2_addr = return_image_1_addr + return_image_1_size;
112134
memcpy(return_image_1_addr, matNormalised.data, return_image_1_size);
113-
memcpy(return_image_2_addr, matBinary.data, return_image_2_size);
135+
memcpy(return_image_2_addr, matUnwarped.data, return_image_2_size);
114136

115137
return_data[0] = bb.x;
116138
return_data[1] = bb.y;

src/index.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ const clearCanvas = canvasId => {
111111
ctx.clearRect(0, 0, canvas.width, canvas.height)
112112
}
113113

114-
const deleteChildren = parent => {
114+
const deleteChildren = elementId => {
115+
const parent = document.getElementById(elementId)
115116
while (parent.firstChild) {
116117
parent.removeChild(parent.firstChild)
117118
}
@@ -120,10 +121,10 @@ const deleteChildren = parent => {
120121
const reset = () => {
121122
clearCanvas('output-image-1')
122123
clearCanvas('output-image-1-overlay')
123-
const cells1Element = document.getElementById('cells-1')
124-
const cells2Element = document.getElementById('cells-2')
125-
deleteChildren(cells1Element)
126-
deleteChildren(cells2Element)
124+
clearCanvas('output-image-2')
125+
clearCanvas('output-image-2-overlay')
126+
deleteChildren('cells-1')
127+
deleteChildren('cells-2')
127128
}
128129

129130
const loadInputImage = async index => {
@@ -163,7 +164,7 @@ const onProcessImage = (module, processImage) => () => {
163164
outImage1Width, outImage1Height, outImage1Channels, outImage1Addr,
164165
outImage2Width, outImage2Height, outImage2Channels, outImage2Addr
165166
] = returnData
166-
const boundingBox = [bbx, bby, bbw, bbh]
167+
const boundingBox1 = [bbx, bby, bbw, bbh]
167168
const corners = range(4).map(cornerIndex => ({
168169
x: returnData[12 + cornerIndex * 2],
169170
y: returnData[12 + cornerIndex * 2 + 1]
@@ -175,7 +176,7 @@ const onProcessImage = (module, processImage) => () => {
175176
? imageDataFrom1Channel(outImage1Data, outImage1Width, outImage1Height)
176177
: imageDataFrom4Channels(outImage1Data, outImage1Width, outImage1Height)
177178
drawOutputImage(imageData1, 'output-image-1')
178-
drawBoundingBox(boundingBox, 'output-image-1-overlay')
179+
drawBoundingBox(boundingBox1, 'output-image-1-overlay')
179180
drawCorners(corners, 'output-image-1-overlay')
180181

181182
const outImage2DataSize = outImage2Width * outImage2Height * outImage2Channels
@@ -184,11 +185,10 @@ const onProcessImage = (module, processImage) => () => {
184185
? imageDataFrom1Channel(outImage2Data, outImage2Width, outImage2Height)
185186
: imageDataFrom4Channels(outImage2Data, outImage2Width, outImage2Height)
186187
drawOutputImage(imageData2, 'output-image-2')
187-
drawBoundingBox(boundingBox, 'output-image-2-overlay')
188-
drawCorners(corners, 'output-image-2-overlay')
188+
const boundingBox2 = [0, 0, imageData2.width, imageData2.height]
189189

190-
cropCells('output-image-1', 'cells-1', boundingBox)
191-
cropCells('output-image-2', 'cells-2', boundingBox)
190+
cropCells('output-image-1', 'cells-1', boundingBox1)
191+
cropCells('output-image-2', 'cells-2', boundingBox2)
192192

193193
module._free(addr)
194194
}

0 commit comments

Comments
 (0)