diff options
author | Marvin Borner | 2019-09-07 00:57:17 +0200 |
---|---|---|
committer | Marvin Borner | 2019-09-07 00:57:17 +0200 |
commit | cd193f40bf3b775e2eb9d0fda7dbe86f165152ac (patch) | |
tree | 85f6881979572d51436cb60445704353a8df093c /scan.js | |
parent | c20db86b195fb88339d87c7b267e523a61bcb6dd (diff) |
NodeJS opencv is dumb so I use python now :)
Diffstat (limited to 'scan.js')
-rw-r--r-- | scan.js | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/scan.js b/scan.js deleted file mode 100644 index b01a65a..0000000 --- a/scan.js +++ /dev/null @@ -1,202 +0,0 @@ -const cv = require("opencv4nodejs"); - -class FinderPattern { - constructor(a, b, c) { - this.topLeft = new cv.Point(a); - this.topRight = new cv.Point(b); - this.bottomLeft = new cv.Point(c); - } -} - -function compareContourAreas(contour1, contour2) { - return contour1.area > contour2.area; -} - -function getContourCenter(vec) { - let x = 0.0; - let y = 0.0; - for (let i = 0; i < vec.size(); i++) { - x += vec[i].x; - y += vec[i].y; - } - return new cv.Point(x / vec.size(), y / vec.size()) -} - -function isContourInsideContour(cont_in, cont_out) { - for (let i = 0; i < cont_in.size(); i++) { - if (cont_out.pointPolygonTest(cont_in[i]) <= 0) return false; - } - return true; -} - -function findLimitedContours(contour, minPix, maxPix) { - const contours = contour.findContours(cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE); - console.log(contours.size()); - let m = 0; - while (m < contours.size()) { - if (contours[m].area <= minPix) { - contours.erase(contours.begin()) - } else if (contours[m].area > maxPix) { - contours.erase(contours.begin()) - } else ++m; - } - console.log(contours.size()); - return contours; -} - -function getContourPair(contours) { - let vectorPair = []; - let flags = Array(contours.size()).fill(false); - for (let i = 0; i < contours.size() - 1; i++) { - if (flags[i]) continue; - let temp = new cv.Contour(); - temp.push_back(contours[i]); - for (let j = i + 1; j < contours.size(); j++) { - if (isContourInsideContour(contours[j], contours[i])) { - temp.push_back(contours[j]); - flags[j] = true; - } - } - if (temp.size() > 1) { - vectorPair.push(temp) - } - } - flags.clear(); - for (let i = 0; i < vectorPair.length; i++) { - vectorPair[i] = vectorPair[i].sort((a, b) => compareContourAreas(a, b)) - } - return vectorPair; -} - -function eliminatePairs(vectorPair, minRatio, maxRatio) { - console.log(maxRatio); - let flag = false; - let m = 0; - while (m < vectorPair.size()) { - flag = false; - if (vectorPair[m].size() < 3) { - vectorPair.erase(vectorPair.begin() + m); - continue; - } - for (let i = 0; i < vectorPair[m].size() - 1; i++) { - const area1 = vectorPair[m][i].area; - const area2 = vectorPair[m][i + 1].area; - if (area1 / area2 < minRatio || area1 / area2 > maxRatio) { - vectorPair.erase(vectorPair.begin() + m); - flag = true; - break; - } - } - if (!flag) { - ++m; - } - } - if (vectorPair.size() > 3) { - eliminatePairs(vectorPair, minRatio, maxRatio * 0.9) - } -} - -function getDistance(a, b) { - return Math.sqrt(((a.x - b.x) ** 2) + (a.y - b.y) ** 2); -} - -function getFinderPattern(vectorPair) { - const point1 = getContourCenter(vectorPair[0][vectorPair[0].size() - 1]); - const point2 = getContourCenter(vectorPair[1][vectorPair[1].size() - 1]); - const point3 = getContourCenter(vectorPair[2][vectorPair[2].size() - 1]); - const distance1 = getDistance(point1, point2); - const distance2 = getDistance(point1, point3); - const distance3 = getDistance(point2, point3); - let x1, y1, x2, y2, x3, y3, p1, p2, p3; - const Max = Math.max.apply(Math, [distance1, distance2, distance3]); - if (Max === distance1) { - p1 = point1; - p2 = point2; - p3 = point3; - } else if (Max === distance2) { - p1 = point1; - p2 = point3; - p3 = point2; - } else { - p1 = point2; - p2 = point3; - p3 = point1; - } - x1 = p1.x; - y1 = p1.y; - x2 = p2.x; - y2 = p2.y; - x3 = p3.x; - y3 = p3.y; - if(x1 === x2){ - if(y1 > y2){ - if(x3 < x1){ - return FinderPattern(p3, p2, p1); - }else{ - return FinderPattern(p3, p1, p2); - } - }else{ - if(x3 < x1){ - return FinderPattern(p3, p1, p2); - }else{ - return FinderPattern(p3, p2, p1); - } - } - }else{ - let newY = (y2 - y1) / (x2 - x1) * x3 + y1 - (y2 - y1) / (x2 - x1) * x1; - if(x1 > x2){ - if(newY < y3){ - return FinderPattern(p3, p2, p1); - }else{ - return FinderPattern(p3, p1, p2); - } - }else{ - if(newY < y3){ - return FinderPattern(p3, p1, p2); - }else{ - return FinderPattern(p3, p2, p1); - } - } - } -} - -const ori = cv.imread("./example.jpg"); -const gray = ori.cvtColor(cv.COLOR_GRAY2BGR); -let canny = new cv.Mat; -gray.copyTo(canny); -const bin = gray.threshold(0, 255, cv.THRESH_OTSU); -let contour = new cv.Mat; -bin.copyTo(contour); -let contours = findLimitedContours(contour, 8.00, 0.2 * ori.cols * ori.rows); - - -if(!contours.empty()) contours = contours.sort((a, b) => compareContourAreas(a, b)); -const vectorPair = getContourPair(contours); -eliminatePairs(vectorPair, 1.0, 10.0); -fPattern = getFinderPattern(vectorPair); -let drawing = new cv.Mat; -ori.copyTo(drawing); - -drawing.drawCircle(fPattern.topLeft, 3, new cv.Vec3(255, 0, 0), 2, 8, 0); -drawing.drawCircle(fPattern.topRight, 3, new cv.Vec3(0,255,0), 2, 8, 0); -drawing.drawCircle(fPattern.bottomLeft, 3, new cv.Vec3(0,0,255), 2, 8, 0); - -let vectorSource = [new cv.Point2(0, 0)]; -let vectorDestination = [new cv.Point2(0, 0)]; -vectorSource.push(fPattern.topLeft); -vectorSource.push(fPattern.topRight); -vectorSource.push(fPattern.bottomLeft); -vectorDestination.push(new cv.Point2(20, 20)); -vectorDestination.push(new cv.Point2(120, 20)); -vectorDestination.push(new cv.Point2(20, 120)); -const affineTrans = cv.getAffineTransform(vectorSource, vectorDestination); -const warped = ori.warpAffine(affineTrans, ori.size()); -const qrColor = warped(new cv.Rect(0, 0, 140, 140)); -const qrColorGray = qrColor.cvtColor(cv.COLOR_GRAY2RGB); -const qrBin = qrColorGray.threshold(0, 255, cv.THRESH_OTSU); - -cv.imshow("binary", bin); -cv.imshow("canny", canny); -cv.imshow("finder patterns", drawing); -cv.imshow("binaried qr code", qrBin); -cv.waitKey(); |