From acc0455415d0456535be8f8b7107ca0092dfc4d9 Mon Sep 17 00:00:00 2001 From: Tamius Han Date: Fri, 11 May 2018 00:49:50 +0200 Subject: [PATCH] EdgeDetection partially moved to its own file --- js/lib/EdgeDetect.js | 400 +++++++++++++++++ js/modules/ArDetect.js | 888 ++------------------------------------ js/modules/DebugCanvas.js | 1 + 3 files changed, 435 insertions(+), 854 deletions(-) create mode 100644 js/lib/EdgeDetect.js diff --git a/js/lib/EdgeDetect.js b/js/lib/EdgeDetect.js new file mode 100644 index 0000000..02f52ff --- /dev/null +++ b/js/lib/EdgeDetect.js @@ -0,0 +1,400 @@ +class EdgeDetect{ + + constructor(ardConf){ + this.conf = ardConf; + + + this.sampleWidthBase = ExtensionConf.arDetect.edgeDetection.sampleWidth << 2; // corrected so we can work on imageData + this.halfSample = this.sampleWidthBase >> 1; + + this.detectionTreshold = ExtensionConf.arDetect.edgeDetection.detectionTreshold; + + this.init(); // initiate things that can change + } + + // initiates things that we may have to change later down the line + init() { + + } + + findEdges(image, sampleCols, direction = EdgeDetectPrimaryDirection.VERTICAL, quality = EdgeDetectQuality.IMPROVED, guardLineOut){ + var fastCandidates, edgeCandidates, edges, + if (direction == EdgeDetectPrimaryDirection.VERTICAL) { + fastCandidates = this.findCandidates(image, sampleCols, guardLine); + + if(quality == EdgeDetectQuality.FAST){ + edges = fastCandidates; + } else { + edgeCandidates = this.edgeDetect(image, edges); + } + } + } + + findCandidates(image, sampleCols, guardLineOut){ + var upper_top, upper_bottom, lower_top, lower_bottom; + var blackbarTreshold; + + var cols_a = sampleCols; + var cols_b = [] + + // todo: cloning can be done better. check array.splice or whatever + for(var i in cols){ + cols_b[i] = cols_a[i] + 0; + } + + var res_top = []; + var res_bottom = []; + + this.colsTreshold = cols.length * ExtensionConf.arDetect.edgeDetection.minColsForSearch; + if(colsTreshold == 0) + colsTreshold = 1; + + this.blackbarTreshold = this.conf.blackLevel + ExtensionConf.arDetect.blackbarTreshold; + + + // if guardline didn't fail and imageDetect did, we don't have to check the upper few pixels + // but only if upper and lower edge are defined. If they're not, we need to check full height + if(guardLineOut){ + if(guardLineOut.imageFail && !guardLineOut.blackbarFail && this.conf.guardLine.blackbar.top) { + upper_top = this.conf.guardLine.blackbar.top; + upper_bottom = this.conf.canvas.height >> 1; + lower_top = upper_bottom; + lower_bottom = this.conf.guardLine.blackbar.bottom; + } else if (! guardLineOut.imageFail && !guardLineOut.blackbarFail && this.conf.guardLine.blackbar.top) { + // ta primer se lahko zgodi tudi zaradi kakšnega logotipa. Ker nočemo, da nam en jeben + // logotip vsili reset razmerja stranic, se naredimo hrvata in vzamemo nekaj varnostnega + // pasu preko točke, ki jo označuje guardLine.blackbar. Recimo 1/8 višine platna na vsaki strani. + // a logo could falsely trigger this case, so we need to add some extra margins past + // the point marked by guardLine.blackbar. Let's say 1/8 of canvas height on either side. + upper_top = 0; + upper_bottom = this.conf.guardLine.blackbar.top + (this.conf.canvas.height >> 3); + lower_top = this.conf.guardLine.blackbar.bottom - (this.conf.canvas.height >> 3); + lower_bottom = this.conf.canvas.height - 1; + } else { + upper_top = 0; + upper_bottom = (this.canvas.height >> 1) /*- parseInt(this.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);*/ + lower_top = (this.canvas.height >> 1) /*+ parseInt(this.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);*/ + lower_bottom = this.canvas.height - 1; + } + } else{ + upper_top = 0; + upper_bottom = (this.canvas.height >> 1) /*- parseInt(this.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);*/ + lower_top = (this.canvas.height >> 1) /*+ parseInt(this.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);*/ + lower_bottom = this.canvas.height - 1; + } + + if(Debug.debug){ + console.log("[EdgeDetect::findCandidates] searching for candidates on ranges", upper_top, "<->", upper_bottom, ";", lower_top, "<->", lower_bottom) + } + + var upper_top_corrected = upper_top * this.conf.canvasImageDataRowLength; + var upper_bottom_corrected = upper_bottom * this.conf.canvasImageDataRowLength; + var lower_top_corrected = lower_top * this.conf.canvasImageDataRowLength; + var lower_bottom_corrected = lower_bottom * this.conf.canvasImageDataRowLength; + + if(Debug.debugCanvas.enabled){ + this._columnTest_dbgc(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false); + this._columnTest_dbgc(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom, true); + } else { + this._columnTest(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false); + this._columnTest(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom, true); + } + + return {res_top: res_top, res_bottom: res_bottom}; + } + + + + // dont call the following outside of this class + + edgeDetect(image, samples){ + var edgeCandidatesTop = {count: 0}; + var edgeCandidatesBottom = {count: 0}; + + var detections; + var canvasWidth = this.conf.canvas.width; + var canvasHeight = this.conf.canvas.height; + + var sampleStart, sampleEnd, loopEnd; + var sampleRow_black, sampleRow_color; + + var blackEdgeViolation = false; + + var topEdgeCount = 0; + var bottomEdgeCount = 0; + + + for(sample of samples.res_top){ + blackEdgeViolation = false; // reset this + + // determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is + sampleStart = (sample.col << 2) - this.halfSample; + + if(sampleStart < 0) + sampleStart = 0; + + sampleEnd = sampleStart + this.sampleWidthBase; + if(sampleEnd > this.conf.canvas.imageDataRowLength) + sampleEnd = this.conf.canvas.imageDataRowLength; + + // calculate row offsets for imageData array + sampleRow_black = (sample.top - ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvas.imageDataRowLength; + sampleRow_color = (sample.top + 1 + ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvas.imageDataRowLength; + + // že ena kršitev črnega roba pomeni, da kandidat ni primeren + // even a single black edge violation means the candidate is not an edge + loopEnd = sampleRow_black + sampleEnd; + + if(Debug.debugCanvas.enabled){ + blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd); + } else { + blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd); + } + + // če je bila črna črta skrunjena, preverimo naslednjega kandidata + // if we failed, we continue our search with the next candidate + if(blackEdgeViolation) + continue; + + detections = 0; + loopEnd = sampleRow_color + sampleEnd; + + if(Debug.debugCanvas.enabled) { + this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample, edgeCandidatesTop) + } else { + this._imageTest(image, start, end, sample, edgeCandidatesBottom) + } + } + + for(sample of samples.res_bottom){ + blackEdgeViolation = false; // reset this + + // determine our bounds. Note that sample.col is _not_ corrected for imageData, but this.halfSample is + sampleStart = (sample.col << 2) - this.halfSample; + + if(sampleStart < 0) + sampleStart = 0; + + sampleEnd = sampleStart + this.sampleWidthBase; + if(sampleEnd > this.conf.canvas.imageDataRowLength) + sampleEnd = this.conf.canvas.imageDataRowLength; + + // calculate row offsets for imageData array + sampleRow_black = (sample.bottom + ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvas.imageDataRowLength; + sampleRow_color = (sample.bottom - 1 - ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvas.imageDataRowLength; + + // že ena kršitev črnega roba pomeni, da kandidat ni primeren + // even a single black edge violation means the candidate is not an edge + loopEnd = sampleRow_black + sampleEnd; + + if(Debug.debugCanvas.enabled){ + blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd); + } else { + blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd); + } + + // če je bila črna črta skrunjena, preverimo naslednjega kandidata + // if we failed, we continue our search with the next candidate + if(blackEdgeViolation) + continue; + + detections = 0; + loopEnd = sampleRow_color + sampleEnd; + + if(Debug.debugCanvas.enabled) { + this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample, edgeCandidatesTop); + } else { + this._imageTest(image, start, end, sample, edgeCandidatesBottom); + } + } + + return { + edgeCandidatesTop: edgeCandidatesTop, + edgeCandidatesTopCount: edgeCandidatesTop.count, + edgeCandidatesBottom: edgeCandidatesBottom, + edgeCandidatesBottomCount: edgeCandidatesBottom.count + }; + } + + + // pomožne funkcije + // helper functions + + _columnTest(image, top, bottom, colsIn, colsOut, reverseSearchDirection){ + var tmpI; + if(reverseSearchDirection){ + for(var i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){ + for(var col of colsIn){ + tmpI = i + (col << 2); + + if( image[tmpI] > this.blackbarTreshold || + image[tmpI + 1] > this.blackbarTreshold || + image[tmpI + 2] > this.blackbarTreshold ){ + + var bottom = (i / this.conf.canvasImageDataRowLength) + 1; + colsOut.push({ + col: col, + bottom: bottom, + bottomRelative: this.canvas.height - bottom + }); + colsIn.splice(colsIn.indexOf(col), 1); + } + } + if(colsIn.length < this.colsTreshold) + break; + } + } else { + for(var i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){ + for(var col of colsIn){ + tmpI = i + (col << 2); + + if( image[tmpI] > this.blackbarTreshold || + image[tmpI + 1] > this.blackbarTreshold || + image[tmpI + 2] > this.blackbarTreshold ){ + + colsOut.push({ + col: col, + top: (i / this.conf.canvasImageDataRowLength) - 1 + }); + colsIn.splice(cols_a.indexOf(col), 1); + } + } + if(colsIn.length < this.colsTreshold) + break; + } + } + } + + _columnTest_dbgc(image, top, bottom, colsIn, colsOut, reverseSearchDirection){ + var tmpI; + if(reverseSearchDirection){ + for(var i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){ + for(var col of colsIn){ + tmpI = i + (col << 2); + + if( image[tmpI] > this.blackbarTreshold || + image[tmpI + 1] > this.blackbarTreshold || + image[tmpI + 2] > this.blackbarTreshold ){ + + var bottom = (i / this.conf.canvasImageDataRowLength) + 1; + colsOut.push({ + col: col, + bottom: bottom, + bottomRelative: this.canvas.height - bottom + }); + colsIn.splice(colsIn.indexOf(col), 1); + this.conf.debugCanvas.trace(tmpI,DebugCanvasClasses.EDGEDETECT_CANDIDATE); + } + else{ + this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_ONBLACK); + } + } + if(colsIn.length < this.colsTreshold) + break; + } + } else { + for(var i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){ + for(var col of colsIn){ + tmpI = i + (col << 2); + + if( image[tmpI] > this.blackbarTreshold || + image[tmpI + 1] > this.blackbarTreshold || + image[tmpI + 2] > this.blackbarTreshold ){ + + colsOut.push({ + col: col, + top: (i / this.conf.canvasImageDataRowLength) - 1 + }); + colsIn.splice(cols_a.indexOf(col), 1); + this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_CANDIDATE); + } else { + this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_ONBLACK); + } + } + if(colsIn.length < this.colsTreshold) + break; + } + } + } + + _blackbarTest(image, start, end){ + for(var i = sampleRow_black + sampleStart; i < loopEnd; i += 4){ + if( image[i ] > this.blackbarTreshold || + image[i+1] > this.blackbarTreshold || + image[i+2] > this.blackbarTreshold ){ + return true; + } + } + return false; // no violation + } + + _blackbarTest_dbg(image, start, end){ + for(var i = start; i < end; i += 4){ + if( image[i ] > this.blackbarTreshold || + image[i+1] > this.blackbarTreshold || + image[i+2] > this.blackbarTreshold ){ + + this.conf.debugCanvas.trace(i, DebugCanvasClasses.VIOLATION) + return true; + } else { + this.conf.debugCanvas.trace(i, DebugCanvasClasses.EDGEDETECT_BLACKBAR) + } + } + + return false; // no violation + } + + _imageTest(image, start, end, sample, edgeCandidates){ + var detections = 0; + + for(var i = start; i < end; i += 4){ + if( image[i ] > this.blackbarTreshold || + image[i+1] > this.blackbarTreshold || + image[i+2] > this.blackbarTreshold ){ + ++detections; + } + } + if(detections >= detectionTreshold){ + if(edgeCandidates[sample.top] != undefined) + edgeCandidates[sample.top].count++; + else{ + edgeCandidates[sample.top] = {top: sample.top, count: 1}; + edgeCandidates.count++; + } + } + } + + _imageTest_dbg(image, start, end, sample, edgeCandidates){ + var detections = 0; + + for(var i = start; i < end; i += 4){ + if( image[i ] > this.blackbarTreshold || + image[i+1] > this.blackbarTreshold || + image[i+2] > this.blackbarTreshold ){ + ++detections; + this.conf.debugCanvas.trace(i, DebugCanvasClasses.EDGEDETECT_IMAGE); + } else { + this.conf.debugCanvas.trace(i, DebugCanvasClasses.WARN); + } + } + if(detections >= this.detectionTreshold){ + if(edgeCandidates[sample.top] != undefined) + edgeCandidates[sample.top].count++; + else{ + edgeCandidates[sample.top] = {top: sample.top, count: 1}; + edgeCandidates.count++; + } + } + } + +} + +var EdgeDetectPrimaryDirection = { + VERTICAL: 0, + HORIZONTAL: 1 +} + +var EdgeDetectQuality = { + FAST: 0, + IMPROVED: 1 +} \ No newline at end of file diff --git a/js/modules/ArDetect.js b/js/modules/ArDetect.js index 035db35..cfdf661 100644 --- a/js/modules/ArDetect.js +++ b/js/modules/ArDetect.js @@ -13,6 +13,9 @@ class ArDetector { } init(){ + this.guardLine = new GuardLine(this); + this.edgeDetector = new EdgeDetect(this); + this.debugCanvas = new DebugCanvas(this); setup(ExtensionConf.arDetect.hSamples, ExtensionConf.arDetect.vSamples); } @@ -455,8 +458,6 @@ class ArDetector { console.log("%c[ArDetect::_ard_vdraw] no edge detected. canvas has no edge.", "color: #aaf"); } - image = null; - // Pogledamo, ali smo že kdaj ponastavili CSS. Če še nismo, potem to storimo. Če smo že, potem ne. // Ponastavimo tudi guardline (na null). // let's chec if we ever reset CSS. If we haven't, then we do so. If we did, then we don't. @@ -468,6 +469,7 @@ class ArDetector { this.guardLine.bottom = null; this.noLetterboxCanvasReset = true; } + triggerTimeout = this.getTimeout(baseTimeout, startTime); this.scheduleFrameCheck(triggerTimeout); //no letterbox, no problem return; @@ -485,48 +487,35 @@ class ArDetector { // poglejmo, če obrežemo preveč. // let's check if we're cropping too much (or whatever) var guardLineOut; - var imageDetectOut; - if(ExtensionConf.arDetect.guardLine.enabled){ - guardLineOut = _ard_guardLineCheck(image, fallbackMode); - - guardLineResult = guardLineOut.success; - if(! guardLineResult ){ // add new ssamples to our sample columns - for(var col of guardLineOut.offenders){ - sampleCols.push(col) - } + guardLineOut = GuardLine.check(image, fallbackMode); + + if (guardLineOut.blackbarFail) { // add new ssamples to our sample columns + for(var col of guardLineOut.offenders){ + sampleCols.push(col) } + } - imageDetectOut = _ard_guardLineImageDetect(image, fallbackMode); - imageDetectResult = imageDetectOut.success; - - // če sta obe funkciji uspeli, potem se razmerje stranic ni spremenilo. - // if both succeed, then aspect ratio hasn't changed. - - // if we're in fallback mode, we restore CSS - if(fallbackMode && ! guardLineResult){ - - - Resizer.reset(); - GlobalVars.lastAr = {type: "auto", ar: null}; - GlobalVars.arDetect.guardLine.top = null; - GlobalVars.arDetect.guardLine.bottom = null; - GlobalVars.arDetect.noLetterboxCanvasReset = true; - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } - - if(imageDetectResult && guardLineResult){ - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } + // če ni padla nobena izmed funkcij, potem se razmerje stranic ni spremenilo + // if both succeed, then aspect ratio hasn't changed. + + // if we're in fallback mode and blackbar test failed, we restore CSS + if (fallbackMode && guardLineOut.blackbarFail) { + this.videoData.resizer.reset({type: "auto", ar: null}); + this.guardLine.reset(); + this.arDetect.noLetterboxCanvasReset = true; + triggerTimeout = this.getTimeout(baseTimeout, startTime); + _ard_vdraw(triggerTimeout); //no letterbox, no problem + return; } + if (!guardLineOut.imageFail && !guardLineOut.blackbarFail) { + triggerTimeout = this.getTimeout(baseTimeout, startTime); + this.scheduleFrameCheck(triggerTimeout); //no letterbox, no problem + return; + } + // će se razmerje stranic spreminja iz ožjega na širšega, potem najprej poglejmo za prisotnostjo navpičnih črnih obrob. // če so prisotne navpične obrobe tudi na levi in desni strani, potlej obstaja možnost, da gre za logo na črnem ozadju. // v tem primeru obstaja nevarnost, da porežemo preveč. Ker obstaja dovolj velika možnost, da bi porezali preveč, rajši @@ -538,20 +527,21 @@ class ArDetector { // a chance of a logo on black background. We could cut easily cut too much. Because there's a somewhat significant chance // that we will cut too much, we rather avoid doing anything at all. There's gonna be a next chance. - if(! imageDetectResult || ! guardLineResult){ + if(guardLineOut.blackbarFail || guardLineOut.imageFail){ if(pillarTest(image)){ - if(Debug.debug && ! guardLineResult){ + if(Debug.debug && guardLineOut.blackbarFail){ console.log("[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio."); } if(! guardLineResult){ - Resizer.reset(); + this.videoData.resizer.reset({type: "auto", ar: null}); + this.guardLine.reset(); } triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); + this.scheduleFrameCheck(triggerTimeout); return; } } @@ -611,209 +601,12 @@ class ArDetector { //#region frameCheck helper functions - guardLineCheck = function(image, fallbackMode){ - // this test tests for whether we crop too aggressively - - // if this test is passed, then aspect ratio probably didn't change from wider to narrower. However, further - // checks are needed to determine whether aspect ratio got wider. - // if this test fails, it returns a list of offending points. - - // if the upper edge is null, then edge hasn't been detected before. This test is pointless, therefore it - // should succeed by default. Also need to check bottom, for cases where only one edge is known - - if(! fallbackMode){ - if(GlobalVars.arDetect.guardLine.top == null || GlobalVars.arDetect.guardLine.bottom == null) - return { success: true }; - - var edges = GlobalVars.arDetect.guardLine; - } - var blackbarTreshold = this.blackLevel + ExtensionConf.arDetect.blackbarTreshold; - - var offset = parseInt(this.canvas.width * ExtensionConf.arDetect.guardLine.ignoreEdgeMargin) << 2; - - var offenders = []; - var firstOffender = -1; - var offenderCount = -1; // doing it this way means first offender has offenderCount==0. Ez index. - - // TODO: implement logo check. - - - // preglejmo obe vrstici - // check both rows - - if(! fallbackMode){ - var edge_upper = edges.top - ExtensionConf.arDetect.guardLine.edgeTolerancePx; - if(edge_upper < 0) - return {success: true}; // if we go out of bounds here, the black bars are negligible - - var edge_lower = edges.bottom + ExtensionConf.arDetect.guardLine.edgeTolerancePx; - if(edge_lower > this.canvas.height - 1) - return {success: true}; // if we go out of bounds here, the black bars are negligible - } - else{ - // fallback mode is a bit different - edge_upper = 0; - edge_lower = this.canvas.height - 1; - } - - var rowStart, rowEnd; - - - // <<<=======| checking upper row |========>>> - - rowStart = ((edge_upper * this.canvas.width) << 2) + offset; - rowEnd = rowStart + ( this.canvas.width << 2 ) - (offset * 2); - - if (Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine) { - offenderCount = this._gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold); - } else { - offenderCount = this._gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold); - } - // <<<=======| checking lower row |========>>> - - rowStart = ((edge_lower * this.canvas.width) << 2) + offset; - rowEnd = rowStart + ( this.canvas.width << 2 ) - (offset * 2); - - if (Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine) { - offenderCount = this._gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold); - } else { - offenderCount = this._gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold); - } - - // če nismo našli nobenih prekrškarjev, vrnemo uspeh. Drugače vrnemo seznam prekrškarjev - // vrnemo tabelo, ki vsebuje sredinsko točko vsakega prekrškarja (x + width*0.5) - // - // if we haven't found any offenders, we return success. Else we return list of offenders - // we return array of middle points of offenders (x + (width * 0.5) for every offender) - - if(offenderCount == -1){ - return {success: true}; - } - - var ret = new Array(offenders.length); - for(var o in offenders){ - ret[o] = offenders[o].x + (offenders[o].width * 0.25); - } - - return {success: false, offenders: ret}; - } - + //#region guard line helper functions - _gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold){ - var firstOffender = -1; - for(var i = rowStart; i < rowEnd; i+=4){ - - // we track sections that go over what's supposed to be a black line, so we can suggest more - // columns to sample - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - if(firstOffender < 0){ - firstOffender = (i - rowStart) >> 2; - offenderCount++; - offenders.push({x: firstOffender, width: 1}); - } - else{ - offenders[offenderCount].width++ - } - } - else{ - // is that a black pixel again? Let's reset the 'first offender' - firstOffender = -1; - } - } - return offenderCount; - } - _gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold){ - var firstOffender = -1; - for(var i = rowStart; i < rowEnd; i+=4){ - - // we track sections that go over what's supposed to be a black line, so we can suggest more - // columns to sample - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - DebugCanvas.trace('guardLine_blackbar_violation', i); - if(firstOffender < 0){ - firstOffender = (i - rowStart) >> 2; - offenderCount++; - offenders.push({x: firstOffender, width: 1}); - } - else{ - offenders[offenderCount].width++ - } - } - else{ - DebugCanvas.trace('guardLine_blackbar', i); - // is that a black pixel again? Let's reset the 'first offender' - firstOffender = -1; - } - - } - - return offenderCount; - } //#endregion - guardLineImageDetect(image){ - if(GlobalVars.arDetect.guardLine.top == null || GlobalVars.arDetect.guardLine.bottom == null) - return { success: false }; - - var blackbarTreshold = this.blackLevel + ExtensionConf.arDetect.blackbarTreshold; - var edges = GlobalVars.arDetect.guardLine; - - var offset = parseInt(this.canvas.width * ExtensionConf.arDetect.guardLine.ignoreEdgeMargin) << 2; - - // TODO: implement logo check. - - - // preglejmo obe vrstici - tukaj po pravilih ne bi smeli iti prek mej platna. ne rabimo preverjati - // check both rows - by the rules and definitions, we shouldn't go out of bounds here. no need to check, then - - // if(fallbackMode){ - // var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx; - // var edge_lower = this.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1; - // } - // else{ - var edge_upper = edges.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx; - var edge_lower = edges.bottom - ExtensionConf.arDetect.guardLine.edgeTolerancePx; - // } - - // koliko pikslov rabimo zaznati, da je ta funkcija uspe. Tu dovoljujemo tudi, da so vsi piksli na enem - // robu (eden izmed robov je lahko v celoti črn) - // how many non-black pixels we need to consider this check a success. We only need to detect enough pixels - // on one edge (one of the edges can be black as long as both aren't) - var successTreshold = parseInt(this.canvas.width * ExtensionConf.arDetect.guardLine.imageTestTreshold); - var rowStart, rowEnd; - - - // <<<=======| checking upper row |========>>> - - rowStart = ((edge_upper * this.canvas.width) << 2) + offset; - rowEnd = rowStart + ( this.canvas.width << 2 ) - (offset * 2); - - var res = false; - - if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){ - res = _ard_ti_debugCheckRow(image, rowStart, rowEnd, successTreshold, blackbarTreshold); - } else { - res = _ard_ti_checkRow(image, rowStart, rowEnd,successTreshold, blackbarTreshold); - } - - if(res) - return {success: true}; - - - // <<<=======| checking lower row |========>>> - - rowStart = ((edge_lower * this.canvas.width) << 2) + offset; - // rowEnd = rowStart + ( this.canvas.width << 2 ) - (offset * 2); - - if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){ - res = _ard_ti_debugCheckRow(image, rowStart, rowEnd, successTreshold); - } else { - res = _ard_ti_checkRow(image, rowStart, rowEnd,successTreshold); - } - - return {success: res}; - } + //#endregion } @@ -824,343 +617,6 @@ if(Debug.debug) var _ard_console_stop = "background: #000; color: #f41"; var _ard_console_start = "background: #000; color: #00c399"; - - - - -var _ard_vdraw_but_for_reals = function() { - // thanks dude: - // https://www.reddit.com/r/iiiiiiitttttttttttt/comments/80qnss/i_tried_to_write_something_that_would/duyfg53/ - // except this method stops working as soon as I try to do something with the image :/ - - if(this._forcehalt) - return; - - if(! GlobalVars.video){ - if(Debug.debug || Debug.warnings_critical) - console.log("[ArDetect::_ard_vdraw] Video went missing. Stopping current instance of automatic detection and trying to start a new one.") - _ard_stop(); - this._forcehalt = true; - _arSetup(); - return; - } - - var fallbackMode = false; - var startTime = performance.now(); - var baseTimeout = ExtensionConf.arDetect.timer_playing; - var triggerTimeout; - - var guardLineResult = true; // true if success, false if fail. true by default - var imageDetectResult = false; // true if we detect image along the way. false by default - - var sampleCols = []; - for(var i in _ard_sampleCols){ - sampleCols[i] = _ard_sampleCols[i]; - } - - var how_far_treshold = 8; // how much can the edge pixel vary (*4) - - if(GlobalVars.video == null || GlobalVars.video.ended || Status.arStrat != "auto"){ - // we slow down if ended, null, or not auto. Detecting is pointless. - - _ard_vdraw(ExtensionConf.arDetect.timer_paused); - return false; - } - - if(GlobalVars.video.paused){ - // if the video is paused, we still do autodetection. We just increase the interval. - baseTimeout = ExtensionConf.arDetect.timer_paused; - } - - - - try{ - this.context.drawImage(GlobalVars.video, 0,0, this.canvas.width, this.canvas.height); - } - catch(ex){ - if(Debug.debug) - console.log("%c[ArDetect::_ard_vdraw] can't draw image on canvas. Trying canvas.drawWindow instead", "color:#000; backgroud:#f51;", ex); - - try{ - if(! ExtensionConf.arDetect.fallbackMode.enabled) - throw "fallbackMode is disabled."; - - if(_ard_canvasReadyForDrawWindow()){ - this.context.drawWindow(window, _ard_canvasDrawWindowHOffset, 0, this.canvas.width, this.canvas.height, "rgba(0,0,0,1)"); - - if(Debug.debug) - console.log("%c[ArDetect::_ard_vdraw] canvas.drawImage seems to have worked", "color:#000; backgroud:#2f5;"); - fallbackMode = true; - } - else{ - // canvas needs to be resized, so let's change setup - _ard_stop(); - - var newCanvasWidth = window.innerHeight * (GlobalVars.video.videoWidth / GlobalVars.video.videoHeight); - var newCanvasHeight = window.innerHeight; - - if(ExtensionConf.miscFullscreenSettings.videoFloat == "center") - _ard_canvasDrawWindowHOffset = Math.round((window.innerWidth - newCanvasWidth) * 0.5); - else if(ExtensionConf.miscFullscreenSettings.videFloat == "left") - _ard_canvasDrawWindowHOffset = 0; - else - _ard_canvasDrawWindowHOffset = window.innerWidth - newCanvasWidth; - - _arSetup(newCanvasWidth, newCanvasHeight); - - return; - } - - } - catch(ex){ - if(Debug.debug) - console.log("%c[ArDetect::_ard_vdraw] okay this didnt work either", "color:#000; backgroud:#f51;", ex); - - _ard_vdraw( ExtensionConf.arDetect.timer_error ); - return; - } - } - - if(this.blackLevel == undefined){ - if(Debug.debugArDetect) - console.log("[ArDetect::_ard_vdraw] black level undefined, resetting"); - - _ard_resetBlackLevel(); - } - - // we get the entire frame so there's less references for garbage collection to catch - var image = this.context.getImageData(0,0,this.canvas.width,this.canvas.height).data; - - if(Debug.debugCanvas.enabled){ - DebugCanvas.showTraces(); - DebugCanvas.setBuffer(image); - } - - // fast test to see if aspect ratio is correct. If we detect anything darker than blackLevel, we modify - // blackLevel to the new lowest value - var isLetter=true; - var currentMaxVal = 0; - var currentMax_a; - var currentMinVal = 48; // not 255 cos safety, even this is prolly too high - var currentMin_a; - - var rowOffset = 0; - var colOffset_r, colOffset_g, colOffset_b; - - // detect black level. if currentMax and currentMin vary too much, we automatically know that - // black level is bogus and that we aren't letterboxed. We still save the darkest value as black level, - // though — as black bars will never be brighter than that. - - for(var i = 0; i < sampleCols.length; ++i){ - colOffset_r = sampleCols[i] << 2; - colOffset_g = colOffset_r + 1; - colOffset_b = colOffset_r + 2; - - currentMax_a = image[colOffset_r] > image[colOffset_g] ? image[colOffset_r] : image[colOffset_g]; - currentMax_a = currentMax_a > image[colOffset_b] ? currentMax_a : image[colOffset_b]; - - currentMaxVal = currentMaxVal > currentMax_a ? currentMaxVal : currentMax_a; - - currentMin_a = image[colOffset_r] < image[colOffset_g] ? image[colOffset_r] : image[colOffset_g]; - currentMin_a = currentMin_a < image[colOffset_b] ? currentMin_a : image[colOffset_b]; - - currentMinVal = currentMinVal < currentMin_a ? currentMinVal : currentMin_a; - } - - // we'll shift the sum. math says we can do this - rowOffset = this.canvas.width * (this.canvas.height - 1); - - for(var i = 0; i < sampleCols.length; ++i){ - colOffset_r = (rowOffset + sampleCols[i]) << 2; - colOffset_g = colOffset_r + 1; - colOffset_b = colOffset_r + 2; - - currentMax_a = image[colOffset_r] > image[colOffset_g] ? image[colOffset_r] : image[colOffset_g]; - currentMax_a = currentMax_a > image[colOffset_b] ? currentMax_a : image[colOffset_b]; - - currentMaxVal = currentMaxVal > currentMax_a ? currentMaxVal : currentMax_a; - - currentMin_a = image[colOffset_r] < image[colOffset_g] ? image[colOffset_r] : image[colOffset_g]; - currentMin_a = currentMin_a < image[colOffset_b] ? currentMin_a : image[colOffset_b]; - - if(currentMinVal == undefined && currenMinVal != undefined) - currentMinVal = currentMin_a; - else if(currentMin_a != undefined) - currentMinVal = currentMinVal < currentMin_a ? currentMinVal : currentMin_a; - - } - - // save black level only if defined - if(currentMinVal != undefined) - this.blackLevel = this.blackLevel < currentMinVal ? this.blackLevel : currentMinVal; - - // this means we don't have letterbox - if ( currentMaxVal > (this.blackLevel + ExtensionConf.arDetect.blackbarTreshold) || (currentMaxVal - currentMinVal) > ExtensionConf.arDetect.blackbarTreshold ){ - - // Če ne zaznamo letterboxa, kličemo reset. Lahko, da je bilo razmerje stranic popravljeno na roke. Možno je tudi, - // da je letterbox izginil. - // If we don't detect letterbox, we reset aspect ratio to aspect ratio of the video file. The aspect ratio could - // have been corrected manually. It's also possible that letterbox (that was there before) disappeared. - if(Debug.debug){ - console.log("%c[ArDetect::_ard_vdraw] no edge detected. canvas has no edge.", "color: #aaf"); - } - - image = null; - - // Pogledamo, ali smo že kdaj ponastavili CSS. Če še nismo, potem to storimo. Če smo že, potem ne. - // Ponastavimo tudi guardline (na null). - // let's chec if we ever reset CSS. If we haven't, then we do so. If we did, then we don't. - // while resetting the CSS, we also reset guardline top and bottom back to null. - - if(! GlobalVars.arDetect.noLetterboxCanvasReset){ - Resizer.reset(); - GlobalVars.lastAr = {type: "auto", ar: null}; - GlobalVars.arDetect.guardLine.top = null; - GlobalVars.arDetect.guardLine.bottom = null; - GlobalVars.arDetect.noLetterboxCanvasReset = true; - } - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } - - // Če preverjamo naprej, potem moramo postaviti to vrednost nazaj na 'false'. V nasprotnem primeru se bo - // css resetiral enkrat na video/pageload namesto vsakič, ko so za nekaj časa obrobe odstranejene - // if we look further we need to reset this value back to false. Otherwise we'll only get CSS reset once - // per video/pageload instead of every time letterbox goes away (this can happen more than once per vid) - GlobalVars.arDetect.noLetterboxCanvasReset = false; - - // let's do a quick test to see if we're on a black frame - // TODO: reimplement but with less bullshit - - // poglejmo, če obrežemo preveč. - // let's check if we're cropping too much (or whatever) - var guardLineOut; - var imageDetectOut; - - if(ExtensionConf.arDetect.guardLine.enabled){ - guardLineOut = _ard_guardLineCheck(image, fallbackMode); - - guardLineResult = guardLineOut.success; - if(! guardLineResult ){ // add new ssamples to our sample columns - for(var col of guardLineOut.offenders){ - sampleCols.push(col) - } - } - - imageDetectOut = _ard_guardLineImageDetect(image, fallbackMode); - imageDetectResult = imageDetectOut.success; - - // če sta obe funkciji uspeli, potem se razmerje stranic ni spremenilo. - // if both succeed, then aspect ratio hasn't changed. - - // if we're in fallback mode, we restore CSS - if(fallbackMode && ! guardLineResult){ - - - Resizer.reset(); - GlobalVars.lastAr = {type: "auto", ar: null}; - GlobalVars.arDetect.guardLine.top = null; - GlobalVars.arDetect.guardLine.bottom = null; - GlobalVars.arDetect.noLetterboxCanvasReset = true; - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } - - if(imageDetectResult && guardLineResult){ - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } - - } - - // će se razmerje stranic spreminja iz ožjega na širšega, potem najprej poglejmo za prisotnostjo navpičnih črnih obrob. - // če so prisotne navpične obrobe tudi na levi in desni strani, potlej obstaja možnost, da gre za logo na črnem ozadju. - // v tem primeru obstaja nevarnost, da porežemo preveč. Ker obstaja dovolj velika možnost, da bi porezali preveč, rajši - // ne naredimo ničesar. - // - // če je pillarbox zaznan v primeru spremembe iz ožjega na širše razmerje stranice, razmerje povrnemo na privzeto vrednost. - // - // If aspect ratio changes from narrower to wider, we first check for presence of pillarbox. Presence of pillarbox indicates - // a chance of a logo on black background. We could cut easily cut too much. Because there's a somewhat significant chance - // that we will cut too much, we rather avoid doing anything at all. There's gonna be a next chance. - - if(! imageDetectResult || ! guardLineResult){ - if(pillarTest(image)){ - - if(Debug.debug && ! guardLineResult){ - console.log("[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio."); - } - - if(! guardLineResult){ - Resizer.reset(); - } - - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); - return; - } - } - - // pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa. - // let's see where black bars end. - GlobalVars.sampleCols_current = sampleCols.length; - - // blackSamples -> {res_top, res_bottom} - var blackbarSamples = _ard_findBlackbarLimits(image, sampleCols, guardLineResult, imageDetectResult); - - var edgeCandidates = _ard_edgeDetect(image, blackbarSamples); - var edgePost = _ard_edgePostprocess(edgeCandidates, this.canvas.height); - - // console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", this.blackLevel + ExtensionConf.arDetect.blackbarTreshold); - - if(edgePost.status == "ar_known"){ - // zaznali smo rob — vendar pa moramo pred obdelavo še preveriti, ali ni "rob" slučajno besedilo. Če smo kot rob pofočkali - // besedilo, potem to ni veljaven rob. Razmerja stranic se zato ne bomo pipali. - // we detected an edge — but before we process it, we need to check if the "edge" isn't actually some text. If the detected - // edge is actually some text on black background, we shouldn't touch the aspect ratio. Whatever we detected is invalid. - var textEdge = false;; - - if(edgePost.guardLineTop != null){ - var row = edgePost.guardLineTop + ~~(this.canvas.height * ExtensionConf.arDetect.textLineTest.testRowOffset); - textEdge |= textLineTest(image, row); - } - if(edgePost.guardLineTop != null){ - var row = edgePost.guardLineTop - ~~(this.canvas.height * ExtensionConf.arDetect.textLineTest.testRowOffset); - textEdge |= textLineTest(image, row); - } - - if(!textEdge){ - _ard_processAr(GlobalVars.video, this.canvas.width, this.canvas.height, edgePost.blackbarWidth, null, fallbackMode); - - // we also know edges for guardline, so set them - GlobalVars.arDetect.guardLine.top = edgePost.guardLineTop; - GlobalVars.arDetect.guardLine.bottom = edgePost.guardLineBottom; - } - else{ - console.log("detected text on edges, dooing nothing") - } - - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } - else{ - - triggerTimeout = this.getTimeout(baseTimeout, startTime); - _ard_vdraw(triggerTimeout); //no letterbox, no problem - return; - } - - -} - var pillarTest = function(image){ // preverimo, če na sliki obstajajo navpične črne obrobe. Vrne 'true' če so zaznane (in če so približno enako debele), 'false' sicer. // true vrne tudi, če zaznamo preveč črnine. @@ -1316,194 +772,6 @@ var textLineTest = function(image, row){ return false; } -var _ard_gl_rowCheck = function(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold){ - var firstOffender = -1; - for(var i = rowStart; i < rowEnd; i+=4){ - - // we track sections that go over what's supposed to be a black line, so we can suggest more - // columns to sample - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - if(firstOffender < 0){ - firstOffender = (i - rowStart) >> 2; - offenderCount++; - offenders.push({x: firstOffender, width: 1}); - } - else{ - offenders[offenderCount].width++ - } - } - else{ - // is that a black pixel again? Let's reset the 'first offender' - firstOffender = -1; - } - } - - return offenderCount; -} -var _ard_gl_debugRowCheck = function(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold){ - var firstOffender = -1; - for(var i = rowStart; i < rowEnd; i+=4){ - - // we track sections that go over what's supposed to be a black line, so we can suggest more - // columns to sample - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - DebugCanvas.trace('guardLine_blackbar_violation', i); - if(firstOffender < 0){ - firstOffender = (i - rowStart) >> 2; - offenderCount++; - offenders.push({x: firstOffender, width: 1}); - } - else{ - offenders[offenderCount].width++ - } - } - else{ - DebugCanvas.trace('guardLine_blackbar', i); - // is that a black pixel again? Let's reset the 'first offender' - firstOffender = -1; - } - - } - - return offenderCount; -} - -var _ard_edgeDetect = function(image, samples){ - var edgeCandidatesTop = {}; - var edgeCandidatesBottom = {}; - - var sampleWidthBase = ExtensionConf.arDetect.edgeDetection.sampleWidth << 2; // corrected so we can work on imagedata - var halfSample = sampleWidthBase * 0.5; - var detections; - var detectionTreshold = ExtensionConf.arDetect.edgeDetection.detectionTreshold; - var canvasWidth = this.canvas.width; - var canvasHeight = this.canvas.height; - - var sampleStart, sampleEnd, loopEnd; - var sampleRow_black, sampleRow_color; - - var blackEdgeViolation = false; - var blackbarTreshold = this.blackLevel + ExtensionConf.arDetect.blackbarTreshold; - - var topEdgeCount = 0; - var bottomEdgeCount = 0; - - - for(sample of samples.res_top){ - blackEdgeViolation = false; // reset this - - // determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is - sampleStart = (sample.col << 2) - halfSample; - - if(sampleStart < 0) - sampleStart = 0; - - sampleEnd = sampleStart + sampleWidthBase; - if(sampleEnd > this.canvas.imageDataRowLength) - sampleEnd = this.canvas.imageDataRowLength; - - // calculate row offsets for imageData array - sampleRow_black = (sample.top - ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.canvas.imageDataRowLength; - sampleRow_color = (sample.top + 1 + ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.canvas.imageDataRowLength; - - // že ena kršitev črnega roba pomeni, da kandidat ni primeren - // even a single black edge violation means the candidate is not an edge - loopEnd = sampleRow_black + sampleEnd; - for(var i = sampleRow_black + sampleStart; i < loopEnd; i += 4){ - if( image[i ] > blackbarTreshold || - image[i+1] > blackbarTreshold || - image[i+2] > blackbarTreshold ){ - blackEdgeViolation = true; - break; - } - } - - // če je bila črna črta skrunjena, preverimo naslednjega kandidata - // if we failed, we continue our search with the next candidate - if(blackEdgeViolation) - continue; - - detections = 0; - loopEnd = sampleRow_color + sampleEnd; - for(var i = sampleRow_color + sampleStart; i < loopEnd; i += 4){ - if( image[i ] > blackbarTreshold || - image[i+1] > blackbarTreshold || - image[i+2] > blackbarTreshold ){ - ++detections; - } - } - if(detections >= detectionTreshold){ - if(edgeCandidatesTop[sample.top] != undefined) - edgeCandidatesTop[sample.top].count++; - else{ - topEdgeCount++; // only count distinct - edgeCandidatesTop[sample.top] = {top: sample.top, count: 1}; - } - } - } - - for(sample of samples.res_bottom){ - blackEdgeViolation = false; // reset this - - // determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is - sampleStart = (sample.col << 2) - halfSample; - - if(sampleStart < 0) - sampleStart = 0; - - sampleEnd = sampleStart + sampleWidthBase; - if(sampleEnd > this.canvas.imageDataRowLength) - sampleEnd = this.canvas.imageDataRowLength; - - // calculate row offsets for imageData array - sampleRow_black = (sample.bottom + ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.canvas.imageDataRowLength; - sampleRow_color = (sample.bottom - 1 - ExtensionConf.arDetect.edgeDetection.edgeTolerancePx) * this.canvas.imageDataRowLength; - - // že ena kršitev črnega roba pomeni, da kandidat ni primeren - // even a single black edge violation means the candidate is not an edge - loopEnd = sampleRow_black + sampleEnd; - for(var i = sampleRow_black + sampleStart; i < loopEnd; i += 4){ - if( image[i ] > blackbarTreshold || - image[i+1] > blackbarTreshold || - image[i+2] > blackbarTreshold ){ - blackEdgeViolation = true; - break; - } - } - - // če je bila črna črta skrunjena, preverimo naslednjega kandidata - // if we failed, we continue our search with the next candidate - if(blackEdgeViolation) - continue; - - detections = 0; - loopEnd = sampleRow_color + sampleEnd; - for(var i = sampleRow_color + sampleStart; i < loopEnd; i += 4){ - if( image[i ] > blackbarTreshold || - image[i+1] > blackbarTreshold || - image[i+2] > blackbarTreshold ){ - ++detections; - } - } - if(detections >= detectionTreshold){ - if(edgeCandidatesBottom[sample.bottom] != undefined) - edgeCandidatesBottom[sample.bottom].count++; - else{ - bottomEdgeCount++; // only count distinct - edgeCandidatesBottom[sample.bottom] = {bottom: sample.bottom, bottomRelative: sample.bottomRelative, count: 1}; - } - } - } - - return { - edgeCandidatesTop: edgeCandidatesTop, - edgeCandidatesTopCount: topEdgeCount, - edgeCandidatesBottom: edgeCandidatesBottom, - edgeCandidatesBottomCount: bottomEdgeCount - }; -} - - @@ -1615,95 +883,7 @@ var _ard_findBlackbarLimits = function(image, cols, guardLineResult, imageDetect return {res_top: res_top, res_bottom: res_bottom}; } -function _ard_guardLineImageDetect(image, fallbackMode){ - if(GlobalVars.arDetect.guardLine.top == null || GlobalVars.arDetect.guardLine.bottom == null) - return { success: false }; - - var blackbarTreshold = this.blackLevel + ExtensionConf.arDetect.blackbarTreshold; - var edges = GlobalVars.arDetect.guardLine; - - var offset = parseInt(this.canvas.width * ExtensionConf.arDetect.guardLine.ignoreEdgeMargin) << 2; - - // TODO: implement logo check. - - - // preglejmo obe vrstici - tukaj po pravilih ne bi smeli iti prek mej platna. ne rabimo preverjati - // check both rows - by the rules and definitions, we shouldn't go out of bounds here. no need to check, then - - // if(fallbackMode){ - // var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx; - // var edge_lower = this.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1; - // } - // else{ - var edge_upper = edges.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx; - var edge_lower = edges.bottom - ExtensionConf.arDetect.guardLine.edgeTolerancePx; - // } - - // koliko pikslov rabimo zaznati, da je ta funkcija uspe. Tu dovoljujemo tudi, da so vsi piksli na enem - // robu (eden izmed robov je lahko v celoti črn) - // how many non-black pixels we need to consider this check a success. We only need to detect enough pixels - // on one edge (one of the edges can be black as long as both aren't) - var successTreshold = parseInt(this.canvas.width * ExtensionConf.arDetect.guardLine.imageTestTreshold); - var rowStart, rowEnd; - - - // <<<=======| checking upper row |========>>> - - rowStart = ((edge_upper * this.canvas.width) << 2) + offset; - rowEnd = rowStart + ( this.canvas.width << 2 ) - (offset * 2); - - var res = false; - - if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){ - res = _ard_ti_debugCheckRow(image, rowStart, rowEnd, successTreshold, blackbarTreshold); - } else { - res = _ard_ti_checkRow(image, rowStart, rowEnd,successTreshold, blackbarTreshold); - } - - if(res) - return {success: true}; - - - // <<<=======| checking lower row |========>>> - - rowStart = ((edge_lower * this.canvas.width) << 2) + offset; - // rowEnd = rowStart + ( this.canvas.width << 2 ) - (offset * 2); - - if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){ - res = _ard_ti_debugCheckRow(image, rowStart, rowEnd, successTreshold); - } else { - res = _ard_ti_checkRow(image, rowStart, rowEnd,successTreshold); - } - - return {success: res}; -} -function _ard_ti_checkRow(image, rowStart, rowEnd, successTreshold, blackbarTreshold) { - for(var i = rowStart; i < rowEnd; i+=4){ - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - if(successTreshold --<= 0){ - return true; - } - } - } - - return false; -} - -function _ard_ti_debugCheckRow(image, rowStart, rowEnd, successTreshold, blackbarTreshold) { - for(var i = rowStart; i < rowEnd; i+=4){ - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - DebugCanvas.trace('guardLine_imageTest', i); - if(successTreshold --<= 0){ - return true; - } - } else { - DebugCanvas.trace('guardLine_imageTest_noimage', i); - } - } - - return false; -} var _ard_edgePostprocess = function(edges, canvasHeight){ var edgesTop = []; diff --git a/js/modules/DebugCanvas.js b/js/modules/DebugCanvas.js index 967475f..00691d7 100644 --- a/js/modules/DebugCanvas.js +++ b/js/modules/DebugCanvas.js @@ -83,6 +83,7 @@ DebugCanvasClasses = { GUARDLINE_IMAGE: {color: '#000088', colorRgb: [0, 0, 136], text: 'guardline/image (expected value)'}, EDGEDETECT_ONBLACK: {color: '#444444', colorRgb: [68, 68, 68], text: 'edge detect - perpendicular (to edge)'}, + EDGEDETECT_CANDIDATE: {color: '#FFFFFF', colorRgb: [255, 255, 255], text: 'edge detect - edge candidate'}, EDGEDETECT_BLACKBAR: {color: '#07ac93', colorRgb: [7, 172, 147], text: 'edge detect - parallel, black test'}, EDGEDETECT_IMAGE: {color: '#046c5c', colorRgb: [4, 108, 92], text: 'edge detect - parallel, image test'} } \ No newline at end of file