From 3d0c6926dbe667bc3feb3665c468e4a2800e6fe6 Mon Sep 17 00:00:00 2001 From: Tamius Han Date: Thu, 21 Feb 2019 21:21:25 +0100 Subject: [PATCH] Automatic detection is now checking for gradients. Autodetection is slower because of that. --- src/ext/conf/Debug.js | 2 +- src/ext/conf/ExtensionConf.js | 2 +- .../lib/ar-detect/edge-detect/EdgeDetect.js | 206 ++++++++++++++++-- src/ext/lib/video-transform/Resizer.js | 11 +- 4 files changed, 199 insertions(+), 22 deletions(-) diff --git a/src/ext/conf/Debug.js b/src/ext/conf/Debug.js index 81dfb05..bd2e252 100644 --- a/src/ext/conf/Debug.js +++ b/src/ext/conf/Debug.js @@ -8,7 +8,7 @@ var Debug = { debug: true, // debug: false, // keyboard: true, - debugResizer: true, + // debugResizer: true, debugArDetect: true, // debugStorage: false, // debugStorage: true, diff --git a/src/ext/conf/ExtensionConf.js b/src/ext/conf/ExtensionConf.js index a3a4b48..0a688dc 100644 --- a/src/ext/conf/ExtensionConf.js +++ b/src/ext/conf/ExtensionConf.js @@ -55,7 +55,7 @@ var ExtensionConf = { treshold: 16, // if pixel is darker than the sum of black level and this value, we count it as black // on 0-255. Needs to be fairly high (8 might not cut it) due to compression // artifacts in the video itself - imageTreshold: 16, // in order to detect pixel as "not black", the pixel must be brighter than + imageTreshold: 8, // in order to detect pixel as "not black", the pixel must be brighter than // the sum of black level, treshold and this value. gradientTreshold: 2, // When trying to determine thickness of the black bars, we take 2 values: position of // the last pixel that's darker than our treshold, and position of the first pixel that's diff --git a/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js b/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js index 6cd1beb..c0328cb 100644 --- a/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js +++ b/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js @@ -3,6 +3,10 @@ import EdgeStatus from './enums/EdgeStatusEnum'; import EdgeDetectQuality from './enums/EdgeDetectQualityEnum'; import EdgeDetectPrimaryDirection from './enums/EdgeDetectPrimaryDirectionEnum'; +if (Debug.debug) { + console.log("Loading EdgeDetect.js"); +} + class EdgeDetect{ constructor(ardConf){ @@ -42,26 +46,35 @@ class EdgeDetect{ } findCandidates(image, sampleCols, guardLineOut){ - var upper_top, upper_bottom, lower_top, lower_bottom; - var blackbarTreshold; + try { + let upper_top, upper_bottom, lower_top, lower_bottom; - var cols_a = sampleCols.slice(0); - var cols_b = cols_a.slice(0); + // const cols_a = sampleCols.slice(0); + const cols_a = new Array(sampleCols.length); + const res_top_preliminary = new Array(sampleCols.length); - // todo: cloning can be done better. check array.splice or whatever - for(var i in sampleCols){ - cols_b[i] = cols_a[i] + 0; + for (let i = 0; i < cols_a.length; i++) { + cols_a[i] = { + id: i, + value: sampleCols[i], + blackFound: false, + imageFound: false, + }; + res_top_preliminary[i] = {col: undefined, image: undefined, black: undefined}; } + + const cols_b = cols_a.slice(0); + const res_bottom_preliminary = res_top_preliminary.slice(0); - var res_top = []; - var res_bottom = []; + console.log("[EdgeDetect::findCandidates] cols a, b:", cols_a, cols_b); + this.colsTreshold = sampleCols.length * this.settings.active.arDetect.edgeDetection.minColsForSearch; - if(this.colsTreshold == 0) + if (this.colsTreshold == 0) this.colsTreshold = 1; this.blackbarTreshold = this.conf.blackLevel + this.settings.active.arDetect.blackbar.treshold; - + this.imageTreshold = this.blackbarTreshold + this.settings.active.arDetect.blackbar.imageTreshold; // 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 @@ -103,19 +116,58 @@ class EdgeDetect{ 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); - } + // if(Debug.debugCanvas.enabled){ + // this._columnTest_dbgc(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top_preliminary, false); + // this._columnTest_dbgc(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true); + // } else { + // this._columnTest(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top_preliminary, false); + // this._columnTest(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true); + this._columnTest2(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top_preliminary, false); + this._columnTest2(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true); + // } if(Debug.debug && Debug.debugArDetect){ - console.log("[EdgeDetect::findCandidates] candidates found", {res_top: res_top, res_bottom: res_bottom}); + console.log("[EdgeDetect::findCandidates] candidates found -->", {res_top: res_top_preliminary, res_bottom: res_bottom_preliminary}); } + // preglejmo, kateri kandidati so neprimerni. (Neprimerni so tisti, pri katerih se + // 'black' in 'image' razlikujeta za več kot settings.arDetect.blackbar.gradientTreshold) + // + // let's check which candidates are suitable. Suitable candidates have 'black' and 'image' + // components differ by less than settings.arDetect.blackbar.gradientTreshold + + const res_top = []; + const res_bottom = []; + + for (let item of res_top_preliminary) { + if (!item.image) { + continue; + } + if (item.image > -1 && item.image <= item.black + this.settings.active.arDetect.blackbar.gradientTreshold) { + res_top.push({top: item.image, col: item.col}); + } + } + for (let item of res_bottom_preliminary) { + if (!item.image) { + continue; + } + if (item.image >= item.black - this.settings.active.arDetect.blackbar.gradientTreshold) { + res_bottom.push({bottom: item.image, col: item.col}); + } + } + + // const res_top = res_top_preliminary; + // const res_bottom = res_bottom_preliminary; + + if(Debug.debug && Debug.debugArDetect){ + console.log("[EdgeDetect::findCandidates] candidates after processing -->", {res_top: res_top, res_bottom: res_bottom}); + } + return {res_top: res_top, res_bottom: res_bottom}; + + } catch (e) { + console.log("[EdgeDetect::findCandidates] there was an error", e); + } } @@ -475,6 +527,122 @@ class EdgeDetect{ // pomožne funkcije // helper functions + + _columnTest2(image, top, bottom, colsIn, colsOut, reverseSearchDirection) { + let tmpI; + let edgeDetectCount = 0; + if(reverseSearchDirection){ + for(var i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){ + for(let c = 0; c < colsIn.length; c++){ + if (colsIn[c].blackFound && colsIn[c].imageFound) { + // če smo našli obe točki, potem ne pregledujemo več. + // if we found both points, we don't continue anymore + continue; + } + tmpI = i + (colsIn[c].value << 2); + + // najprej preverimo, če je piksel presegel mejo črnega robu + // first we check whether blackbarTreshold was exceeded + if(! colsIn[c].blackFound) { + if( image[tmpI] > this.blackbarTreshold || + image[tmpI + 1] > this.blackbarTreshold || + image[tmpI + 2] > this.blackbarTreshold ){ + + colsOut[c].black = (i / this.conf.canvasImageDataRowLength); + colsOut[c].col = colsIn[c].value; + colsIn[c].blackFound = 1; + console.log("BLACK FOUND AT COL:", colsIn[c].value, '|', colsOut[c].col, "LINE:", colsOut[c].black, colsOut, colsOut[c]) + + // prisili, da se zanka izvede še enkrat ter preveri, + // ali trenuten piksel preseže tudi imageTreshold + // + // force the loop to repeat this step and check whether + // current pixel exceeds imageTreshold as well + c--; + continue; + } + } else { + if (colsIn[c].blackFound++ > this.settings.active.arDetect.blackbar.gradientTreshold) { + colsIn[c].imageFound = true; + continue; + } + // zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da + // predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli + // blackTreshold + // + // then we check whether pixel exceeded imageTreshold + if (image[tmpI] > this.imageTreshold || + image[tmpI + 1] > this.imageTreshold || + image[tmpI + 2] > this.imageTreshold ){ + + colsOut[c].image = (i / this.conf.canvasImageDataRowLength) + colsIn[c].imageFound = true; + edgeDetectCount++; + } + } + } + if(edgeDetectCount >= this.colsTreshold) { + break; + } + } + } else { + for(var i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){ + for(let c = 0; c < colsIn.length; c++){ + if (colsIn[c].blackFound && colsIn[c].imageFound) { + // če smo našli obe točki, potem ne pregledujemo več. + // if we found both points, we don't continue anymore + continue; + } + tmpI = i + (colsIn[c].value << 2); + + // najprej preverimo, če je piksel presegel mejo črnega robu + // first we check whether blackbarTreshold was exceeded + if(! colsIn[c].blackFound) { + if( image[tmpI] > this.blackbarTreshold || + image[tmpI + 1] > this.blackbarTreshold || + image[tmpI + 2] > this.blackbarTreshold ){ + + colsOut[c].black = (i / this.conf.canvasImageDataRowLength); + colsOut[c].col = colsIn[c].value; + colsIn[c].blackFound = true; + console.log("BLACK FOUND AT COL:", colsIn[c].value, '|', colsOut[c].col, "LINE:", colsOut[c].black, colsOut, colsOut[c]) + + // prisili, da se zanka izvede še enkrat ter preveri, + // ali trenuten piksel preseže tudi imageTreshold + // + // force the loop to repeat this step and check whether + // current pixel exceeds imageTreshold as well + c--; + continue; + } + } else { + if (colsIn[c].blackFound++ > this.settings.active.arDetect.blackbar.gradientTreshold) { + colsIn[c].imageFound = true; + continue; + } + // zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da + // predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli + // blackTreshold + // + // then we check whether pixel exceeded imageTreshold + if (image[tmpI] > this.imageTreshold || + image[tmpI + 1] > this.imageTreshold || + image[tmpI + 2] > this.imageTreshold ){ + + colsOut[c].image = (i / this.conf.canvasImageDataRowLength) + colsIn[c].imageFound = true; + edgeDetectCount++; + } + } + } + if(edgeDetectCount >= this.colsTreshold) { + break; + } + } + } + + } + _columnTest(image, top, bottom, colsIn, colsOut, reverseSearchDirection){ var tmpI; if(reverseSearchDirection){ diff --git a/src/ext/lib/video-transform/Resizer.js b/src/ext/lib/video-transform/Resizer.js index e7ccc97..6a09847 100644 --- a/src/ext/lib/video-transform/Resizer.js +++ b/src/ext/lib/video-transform/Resizer.js @@ -7,8 +7,9 @@ import ExtensionMode from '../../../common/enums/extension-mode.enum'; import Stretch from '../../../common/enums/stretch.enum'; import VideoAlignment from '../../../common/enums/video-alignment.enum'; -if(Debug.debug) +if(Debug.debug) { console.log("Loading: Resizer.js"); +} class Resizer { @@ -80,6 +81,10 @@ class Resizer { console.log('[Resizer::setAr] trying to set ar. New ar:', ar) } + if (ar === null) { + return; + } + if(lastAr) { this.lastAr = lastAr; } else { @@ -294,6 +299,10 @@ class Resizer { this.setAr('reset'); } else { + if (this.lastAr && this.lastAr.ar === null) { + console.log("[Resizer::restore] LAST AR IS NULL") + throw "Last ar is null!" + } this.setAr(this.lastAr.ar, this.lastAr) } }