Automatic detection is now checking for gradients. Autodetection is slower because of that.

This commit is contained in:
Tamius Han 2019-02-21 21:21:25 +01:00
parent a0f1a27271
commit 3d0c6926db
4 changed files with 199 additions and 22 deletions

View File

@ -8,7 +8,7 @@ var Debug = {
debug: true, debug: true,
// debug: false, // debug: false,
// keyboard: true, // keyboard: true,
debugResizer: true, // debugResizer: true,
debugArDetect: true, debugArDetect: true,
// debugStorage: false, // debugStorage: false,
// debugStorage: true, // debugStorage: true,

View File

@ -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 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 // on 0-255. Needs to be fairly high (8 might not cut it) due to compression
// artifacts in the video itself // 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. // 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 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 // the last pixel that's darker than our treshold, and position of the first pixel that's

View File

@ -3,6 +3,10 @@ import EdgeStatus from './enums/EdgeStatusEnum';
import EdgeDetectQuality from './enums/EdgeDetectQualityEnum'; import EdgeDetectQuality from './enums/EdgeDetectQualityEnum';
import EdgeDetectPrimaryDirection from './enums/EdgeDetectPrimaryDirectionEnum'; import EdgeDetectPrimaryDirection from './enums/EdgeDetectPrimaryDirectionEnum';
if (Debug.debug) {
console.log("Loading EdgeDetect.js");
}
class EdgeDetect{ class EdgeDetect{
constructor(ardConf){ constructor(ardConf){
@ -42,26 +46,35 @@ class EdgeDetect{
} }
findCandidates(image, sampleCols, guardLineOut){ findCandidates(image, sampleCols, guardLineOut){
var upper_top, upper_bottom, lower_top, lower_bottom; try {
var blackbarTreshold; let upper_top, upper_bottom, lower_top, lower_bottom;
var cols_a = sampleCols.slice(0); // const cols_a = sampleCols.slice(0);
var cols_b = cols_a.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 (let i = 0; i < cols_a.length; i++) {
for(var i in sampleCols){ cols_a[i] = {
cols_b[i] = cols_a[i] + 0; id: i,
value: sampleCols[i],
blackFound: false,
imageFound: false,
};
res_top_preliminary[i] = {col: undefined, image: undefined, black: undefined};
} }
var res_top = []; const cols_b = cols_a.slice(0);
var res_bottom = []; const res_bottom_preliminary = res_top_preliminary.slice(0);
console.log("[EdgeDetect::findCandidates] cols a, b:", cols_a, cols_b);
this.colsTreshold = sampleCols.length * this.settings.active.arDetect.edgeDetection.minColsForSearch; this.colsTreshold = sampleCols.length * this.settings.active.arDetect.edgeDetection.minColsForSearch;
if(this.colsTreshold == 0) if (this.colsTreshold == 0)
this.colsTreshold = 1; this.colsTreshold = 1;
this.blackbarTreshold = this.conf.blackLevel + this.settings.active.arDetect.blackbar.treshold; 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 // 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 // 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_top_corrected = lower_top * this.conf.canvasImageDataRowLength;
var lower_bottom_corrected = lower_bottom * this.conf.canvasImageDataRowLength; var lower_bottom_corrected = lower_bottom * this.conf.canvasImageDataRowLength;
if(Debug.debugCanvas.enabled){ // if(Debug.debugCanvas.enabled){
this._columnTest_dbgc(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false); // 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, true); // this._columnTest_dbgc(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true);
} else { // } else {
this._columnTest(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false); // 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, true); // 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){ 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}; 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 // pomožne funkcije
// helper functions // 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){ _columnTest(image, top, bottom, colsIn, colsOut, reverseSearchDirection){
var tmpI; var tmpI;
if(reverseSearchDirection){ if(reverseSearchDirection){

View File

@ -7,8 +7,9 @@ import ExtensionMode from '../../../common/enums/extension-mode.enum';
import Stretch from '../../../common/enums/stretch.enum'; import Stretch from '../../../common/enums/stretch.enum';
import VideoAlignment from '../../../common/enums/video-alignment.enum'; import VideoAlignment from '../../../common/enums/video-alignment.enum';
if(Debug.debug) if(Debug.debug) {
console.log("Loading: Resizer.js"); console.log("Loading: Resizer.js");
}
class Resizer { class Resizer {
@ -80,6 +81,10 @@ class Resizer {
console.log('[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', ar) console.log('[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', ar)
} }
if (ar === null) {
return;
}
if(lastAr) { if(lastAr) {
this.lastAr = lastAr; this.lastAr = lastAr;
} else { } else {
@ -294,6 +299,10 @@ class Resizer {
this.setAr('reset'); this.setAr('reset');
} }
else { 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) this.setAr(this.lastAr.ar, this.lastAr)
} }
} }