Automatic detection is now checking for gradients. Autodetection is slower because of that.
This commit is contained in:
parent
a0f1a27271
commit
3d0c6926db
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cols_b = cols_a.slice(0);
|
||||||
|
const res_bottom_preliminary = res_top_preliminary.slice(0);
|
||||||
|
|
||||||
var res_top = [];
|
console.log("[EdgeDetect::findCandidates] cols a, b:", cols_a, cols_b);
|
||||||
var res_bottom = [];
|
|
||||||
|
|
||||||
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){
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user