convert ArDetector to ts
This commit is contained in:
parent
7e49b493bb
commit
a3bd8a8b7e
@ -500,7 +500,7 @@ class Settings {
|
|||||||
return this.canStartExtension(site);
|
return this.canStartExtension(site);
|
||||||
}
|
}
|
||||||
|
|
||||||
canStartAutoAr(site) {
|
canStartAutoAr(site?: string) {
|
||||||
// 'site' argument is only ever used when calling this function recursively for debugging
|
// 'site' argument is only ever used when calling this function recursively for debugging
|
||||||
if (!site) {
|
if (!site) {
|
||||||
site = window.location.hostname;
|
site = window.location.hostname;
|
||||||
|
@ -8,10 +8,54 @@ import GuardLine from './GuardLine';
|
|||||||
// import DebugCanvas from './DebugCanvas';
|
// import DebugCanvas from './DebugCanvas';
|
||||||
import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
|
import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
|
||||||
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||||
import {sleep} from '../../lib/Util';
|
import {sleep} from '../Util';
|
||||||
import BrowserDetect from '../../conf/BrowserDetect';
|
import BrowserDetect from '../../conf/BrowserDetect';
|
||||||
|
import Logger from '../Logger';
|
||||||
|
import VideoData from '../video-data/VideoData';
|
||||||
|
import Settings from '../Settings';
|
||||||
|
|
||||||
class ArDetector {
|
class ArDetector {
|
||||||
|
logger: Logger;
|
||||||
|
conf: VideoData;
|
||||||
|
video: HTMLVideoElement;
|
||||||
|
settings: Settings;
|
||||||
|
|
||||||
|
guardLine: GuardLine;
|
||||||
|
edgeDetector: EdgeDetect;
|
||||||
|
|
||||||
|
setupTimer: any;
|
||||||
|
sampleCols: any[];
|
||||||
|
sampleLines
|
||||||
|
|
||||||
|
canFallback: boolean = true;
|
||||||
|
fallbackMode: boolean = false;
|
||||||
|
|
||||||
|
blackLevel: number;
|
||||||
|
|
||||||
|
arid: string;
|
||||||
|
|
||||||
|
// ar detector starts in this state. running main() sets both to false
|
||||||
|
_paused: boolean;
|
||||||
|
_halted: boolean = true;
|
||||||
|
_exited: boolean = true;
|
||||||
|
|
||||||
|
private manualTickEnabled: boolean;
|
||||||
|
_nextTick: boolean;
|
||||||
|
canDoFallbackMode: boolean = false;
|
||||||
|
|
||||||
|
// helper objects
|
||||||
|
private attachedCanvas: HTMLCanvasElement;
|
||||||
|
canvas: HTMLCanvasElement;
|
||||||
|
private blackframeCanvas: HTMLCanvasElement;
|
||||||
|
private context: CanvasRenderingContext2D;
|
||||||
|
private blackframeContext: CanvasRenderingContext2D;
|
||||||
|
private canvasScaleFactor: number;
|
||||||
|
private detectionTimeoutEventCount: number;
|
||||||
|
canvasImageDataRowLength: number;
|
||||||
|
private noLetterboxCanvasReset: boolean;
|
||||||
|
private detectedAr: any;
|
||||||
|
private canvasDrawWindowHOffset: number;
|
||||||
|
private sampleCols_current: number;
|
||||||
|
|
||||||
constructor(videoData){
|
constructor(videoData){
|
||||||
this.logger = videoData.logger;
|
this.logger = videoData.logger;
|
||||||
@ -19,34 +63,18 @@ class ArDetector {
|
|||||||
this.video = videoData.video;
|
this.video = videoData.video;
|
||||||
this.settings = videoData.settings;
|
this.settings = videoData.settings;
|
||||||
|
|
||||||
this.setupTimer = null;
|
|
||||||
|
|
||||||
this.sampleCols = [];
|
this.sampleCols = [];
|
||||||
|
|
||||||
this.canFallback = true;
|
|
||||||
this.fallbackMode = false;
|
|
||||||
|
|
||||||
this.blackLevel = this.settings.active.arDetect.blackbar.blackLevel;
|
this.blackLevel = this.settings.active.arDetect.blackbar.blackLevel;
|
||||||
|
|
||||||
this.arid = (Math.random()*100).toFixed();
|
this.arid = (Math.random()*100).toFixed();
|
||||||
|
|
||||||
// ar detector starts in this state. running main() sets both to false
|
|
||||||
this._halted = true;
|
|
||||||
this._exited = true;
|
|
||||||
|
|
||||||
// we can tick manually, for debugging
|
// we can tick manually, for debugging
|
||||||
this._manualTicks = false;
|
|
||||||
this._nextTick = false;
|
|
||||||
|
|
||||||
this.canDoFallbackMode = false;
|
|
||||||
|
|
||||||
this.drmNotificationShown = false;
|
|
||||||
|
|
||||||
this.logger.log('info', 'init', `[ArDetector::ctor] creating new ArDetector. arid: ${this.arid}`);
|
this.logger.log('info', 'init', `[ArDetector::ctor] creating new ArDetector. arid: ${this.arid}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
setManualTick(manualTick) {
|
setManualTick(manualTick) {
|
||||||
this._manualTicks = manualTick;
|
this.manualTickEnabled = manualTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
@ -68,19 +96,19 @@ class ArDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy(){
|
destroy(){
|
||||||
this.logger.log('info', 'init', `%c[ArDetect::destroy] <@${this.arid}> Destroying aard.`, _ard_console_stop, e);
|
this.logger.log('info', 'init', `%c[ArDetect::destroy] <@${this.arid}> Destroying aard.`, _ard_console_stop);
|
||||||
// this.debugCanvas.destroy();
|
// this.debugCanvas.destroy();
|
||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
setup(cwidth, cheight){
|
setup(cwidth?: number, cheight?: number){
|
||||||
this.logger.log('info', 'init', `[ArDetect::setup] <@${this.arid}> Starting autodetection setup.`);
|
this.logger.log('info', 'init', `[ArDetect::setup] <@${this.arid}> Starting autodetection setup.`);
|
||||||
//
|
//
|
||||||
// [-1] check for zero-width and zero-height videos. If we detect this, we kick the proverbial
|
// [-1] check for zero-width and zero-height videos. If we detect this, we kick the proverbial
|
||||||
// can some distance down the road. This problem will prolly fix itself soon. We'll also
|
// can some distance down the road. This problem will prolly fix itself soon. We'll also
|
||||||
// not do any other setup until this issue is fixed
|
// not do any other setup until this issue is fixed
|
||||||
//
|
//
|
||||||
if(this.video.videoWidth === 0 || this.video.videoHeight === 0 ){
|
if (this.video.videoWidth === 0 || this.video.videoHeight === 0 ){
|
||||||
this.logger.log('warn', 'debug', `[ArDetect::setup] <@${this.arid}> This video has zero width or zero height. Dimensions: ${this.video.videoWidth} × ${this.video.videoHeight}`);
|
this.logger.log('warn', 'debug', `[ArDetect::setup] <@${this.arid}> This video has zero width or zero height. Dimensions: ${this.video.videoWidth} × ${this.video.videoHeight}`);
|
||||||
|
|
||||||
this.scheduleInitRestart();
|
this.scheduleInitRestart();
|
||||||
@ -173,7 +201,7 @@ class ArDetector {
|
|||||||
//
|
//
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.blackframeContext.drawWindow(window,0, 0, this.blackframeCanvas.width, this.blackframeCanvas.height, "rgba(0,0,128,1)");
|
(this.blackframeContext as any).drawWindow(window,0, 0, this.blackframeCanvas.width, this.blackframeCanvas.height, "rgba(0,0,128,1)");
|
||||||
this.canDoFallbackMode = true;
|
this.canDoFallbackMode = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.canDoFallbackMode = false;
|
this.canDoFallbackMode = false;
|
||||||
@ -292,7 +320,7 @@ class ArDetector {
|
|||||||
// state from 'paused' to 'playing', we don't need to wait for the rest of the longer
|
// state from 'paused' to 'playing', we don't need to wait for the rest of the longer
|
||||||
// paused state timeout to finish.
|
// paused state timeout to finish.
|
||||||
|
|
||||||
if ( (!this._manualTicks && this.canTriggerFrameCheck(lastFrameCheckStartTime)) || this._nextTick) {
|
if ( (!this.manualTickEnabled && this.canTriggerFrameCheck(lastFrameCheckStartTime)) || this._nextTick) {
|
||||||
this._nextTick = false;
|
this._nextTick = false;
|
||||||
|
|
||||||
lastFrameCheckStartTime = Date.now();
|
lastFrameCheckStartTime = Date.now();
|
||||||
@ -344,7 +372,7 @@ class ArDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
scheduleInitRestart(timeout, force_reset){
|
scheduleInitRestart(timeout?: number, force_reset?: boolean){
|
||||||
if(! timeout){
|
if(! timeout){
|
||||||
timeout = 100;
|
timeout = 100;
|
||||||
}
|
}
|
||||||
@ -481,7 +509,7 @@ class ArDetector {
|
|||||||
//
|
//
|
||||||
// we can only deny aspect ratio changes if we use automatic mode and if aspect ratio was set from here.
|
// we can only deny aspect ratio changes if we use automatic mode and if aspect ratio was set from here.
|
||||||
|
|
||||||
let arDiff = trueAr - lastAr.ar;
|
let arDiff = trueAr - lastAr.ratio;
|
||||||
|
|
||||||
if (arDiff < 0)
|
if (arDiff < 0)
|
||||||
arDiff = -arDiff;
|
arDiff = -arDiff;
|
||||||
@ -490,7 +518,7 @@ class ArDetector {
|
|||||||
|
|
||||||
// ali je sprememba v mejah dovoljenega? Če da -> fertik
|
// ali je sprememba v mejah dovoljenega? Če da -> fertik
|
||||||
// is ar variance within acceptable levels? If yes -> we done
|
// is ar variance within acceptable levels? If yes -> we done
|
||||||
this.logger.log('info', 'arDetect', `%c[ArDetect::processAr] <@${this.arid}> New aspect ratio varies from the old one by this much:\n`,"color: #aaf","old Ar", lastAr.ar, "current ar", trueAr, "arDiff (absolute):",arDiff,"ar diff (relative to new ar)", arDiff_percent);
|
this.logger.log('info', 'arDetect', `%c[ArDetect::processAr] <@${this.arid}> New aspect ratio varies from the old one by this much:\n`,"color: #aaf","old Ar", lastAr.ratio, "current ar", trueAr, "arDiff (absolute):",arDiff,"ar diff (relative to new ar)", arDiff_percent);
|
||||||
|
|
||||||
if (arDiff < trueAr * this.settings.active.arDetect.allowedArVariance){
|
if (arDiff < trueAr * this.settings.active.arDetect.allowedArVariance){
|
||||||
this.logger.log('info', 'arDetect', `%c[ArDetect::processAr] <@${this.arid}> Aspect ratio change denied — diff %: ${arDiff_percent}`, "background: #740; color: #fa2");
|
this.logger.log('info', 'arDetect', `%c[ArDetect::processAr] <@${this.arid}> Aspect ratio change denied — diff %: ${arDiff_percent}`, "background: #740; color: #fa2");
|
||||||
@ -500,12 +528,12 @@ class ArDetector {
|
|||||||
}
|
}
|
||||||
this.logger.log('info', 'debug', `%c[ArDetect::processAr] <@${this.arid}> Triggering aspect ratio change. New aspect ratio: ${trueAr}`, _ard_console_change);
|
this.logger.log('info', 'debug', `%c[ArDetect::processAr] <@${this.arid}> Triggering aspect ratio change. New aspect ratio: ${trueAr}`, _ard_console_change);
|
||||||
|
|
||||||
this.conf.resizer.updateAr({type: AspectRatioType.Automatic, ratio: trueAr}, {type: AspectRatioType.Automatic, ratio: trueAr});
|
this.conf.resizer.updateAr({type: AspectRatioType.Automatic, ratio: trueAr});
|
||||||
}
|
}
|
||||||
|
|
||||||
clearImageData(id) {
|
clearImageData(id) {
|
||||||
if (ArrayBuffer.transfer) {
|
if ((ArrayBuffer as any).transfer) {
|
||||||
ArrayBuffer.transfer(id, 0);
|
(ArrayBuffer as any).transfer(id, 0);
|
||||||
}
|
}
|
||||||
id = undefined;
|
id = undefined;
|
||||||
}
|
}
|
||||||
@ -579,7 +607,7 @@ class ArDetector {
|
|||||||
this.fallbackMode = true;
|
this.fallbackMode = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.context.drawWindow(window, this.canvasDrawWindowHOffset, 0, this.canvas.width, this.canvas.height, "rgba(0,0,128,1)");
|
(this.context as any).drawWindow(window, this.canvasDrawWindowHOffset, 0, this.canvas.width, this.canvas.height, "rgba(0,0,128,1)");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.log('error', 'arDetect', `%c[ArDetect::frameCheck] can't draw image on canvas with fallback mode either. This error is prolly only temporary.`, "color:#000; backgroud:#f51;", e);
|
this.logger.log('error', 'arDetect', `%c[ArDetect::frameCheck] can't draw image on canvas with fallback mode either. This error is prolly only temporary.`, "color:#000; backgroud:#f51;", e);
|
||||||
return; // it's prolly just a fluke, so we do nothing special here
|
return; // it's prolly just a fluke, so we do nothing special here
|
||||||
@ -680,8 +708,6 @@ class ArDetector {
|
|||||||
this.guardLine.reset();
|
this.guardLine.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerTimeout = this.getTimeout(baseTimeout, startTime);
|
|
||||||
this.scheduleFrameCheck(triggerTimeout);
|
|
||||||
this.clearImageData(imageData);
|
this.clearImageData(imageData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -741,7 +767,7 @@ class ArDetector {
|
|||||||
this.logger.log('error', 'arDetect', `%c[ArDetect::frameCheck] There was a problem setting blackbar. Doing nothing. Error:`, e);
|
this.logger.log('error', 'arDetect', `%c[ArDetect::frameCheck] There was a problem setting blackbar. Doing nothing. Error:`, e);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.guardline.reset();
|
this.guardLine.reset();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// no guardline, no bigge
|
// no guardline, no bigge
|
||||||
}
|
}
|
||||||
@ -780,7 +806,7 @@ class ArDetector {
|
|||||||
let cumulativeValue = 0;
|
let cumulativeValue = 0;
|
||||||
let blackPixelCount = 0;
|
let blackPixelCount = 0;
|
||||||
const bfImageData = this.blackframeContext.getImageData(0, 0, cols, rows).data;
|
const bfImageData = this.blackframeContext.getImageData(0, 0, cols, rows).data;
|
||||||
const blackTreshold = this.blackLevel + this.settings.active.arDetect.blackbar.frameTreshold;
|
const blackTreshold = this.blackLevel + this.settings.active.arDetect.blackbar.frameThreshold;
|
||||||
|
|
||||||
|
|
||||||
// we do some recon for letterbox and pillarbox. While this can't determine whether letterbox/pillarbox exists
|
// we do some recon for letterbox and pillarbox. While this can't determine whether letterbox/pillarbox exists
|
||||||
@ -788,7 +814,7 @@ class ArDetector {
|
|||||||
let rowMax = new Array(rows).fill(0);
|
let rowMax = new Array(rows).fill(0);
|
||||||
let colMax = new Array(cols).fill(0);
|
let colMax = new Array(cols).fill(0);
|
||||||
|
|
||||||
let r, c;
|
let r: number, c: number;
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < bfImageData.length; i+= 4) {
|
for (let i = 0; i < bfImageData.length; i+= 4) {
|
@ -1,13 +1,33 @@
|
|||||||
import Debug from '../../conf/Debug';
|
import Debug from '../../conf/Debug';
|
||||||
|
import Settings from '../Settings';
|
||||||
|
import ArDetector from './ArDetector';
|
||||||
|
|
||||||
|
export type GuardLineBar = {
|
||||||
|
top?: number;
|
||||||
|
bottom?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ImageCheckResult = {
|
||||||
|
success: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
class GuardLine {
|
class GuardLine {
|
||||||
|
blackbar: GuardLineBar;
|
||||||
|
imageBar: GuardLineBar;
|
||||||
|
|
||||||
|
aard: ArDetector;
|
||||||
|
settings: Settings;
|
||||||
|
|
||||||
|
blackbarThreshold: number;
|
||||||
|
imageThreshold: number;
|
||||||
|
|
||||||
|
|
||||||
// ardConf — reference to ArDetector that has current GuardLine instance
|
// ardConf — reference to ArDetector that has current GuardLine instance
|
||||||
constructor(ardConf){
|
constructor (ardConf){
|
||||||
this.blackbar = {top: undefined, bottom: undefined};
|
this.blackbar = {top: undefined, bottom: undefined};
|
||||||
this.imageBar = {top: undefined, bottom: undefined};
|
this.imageBar = {top: undefined, bottom: undefined};
|
||||||
|
|
||||||
this.conf = ardConf;
|
this.aard = ardConf;
|
||||||
this.settings = ardConf.settings;
|
this.settings = ardConf.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +53,7 @@ class GuardLine {
|
|||||||
|
|
||||||
// to odstrani vse neveljavne nastavitve in vse možnosti, ki niso smiselne
|
// to odstrani vse neveljavne nastavitve in vse možnosti, ki niso smiselne
|
||||||
// this removes any configs with invalid values or values that dont make sense
|
// this removes any configs with invalid values or values that dont make sense
|
||||||
if (bbTop < 0 || bbBottom >= this.conf.canvas.height ){
|
if (bbTop < 0 || bbBottom >= this.aard.canvas.height ){
|
||||||
throw {error: "INVALID_SETTINGS_IN_GUARDLINE", bbTop, bbBottom}
|
throw {error: "INVALID_SETTINGS_IN_GUARDLINE", bbTop, bbBottom}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +71,7 @@ class GuardLine {
|
|||||||
check(image, fallbackMode){
|
check(image, fallbackMode){
|
||||||
// izračunaj enkrat in shrani na objekt
|
// izračunaj enkrat in shrani na objekt
|
||||||
// calculate once and save object-instance-wide
|
// calculate once and save object-instance-wide
|
||||||
this.blackbarThreshold = this.conf.blackLevel + this.settings.active.arDetect.blackbar.threshold;
|
this.blackbarThreshold = this.aard.blackLevel + this.settings.active.arDetect.blackbar.threshold;
|
||||||
this.imageThreshold = this.blackbarThreshold + this.settings.active.arDetect.blackbar.imageThreshold;
|
this.imageThreshold = this.blackbarThreshold + this.settings.active.arDetect.blackbar.imageThreshold;
|
||||||
|
|
||||||
// dejansko testiranje
|
// dejansko testiranje
|
||||||
@ -95,7 +115,7 @@ class GuardLine {
|
|||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
var offset = parseInt(this.conf.canvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
var offset = (this.aard.canvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
||||||
|
|
||||||
var offenders = [];
|
var offenders = [];
|
||||||
var offenderCount = -1; // doing it this way means first offender has offenderCount==0. Ez index.
|
var offenderCount = -1; // doing it this way means first offender has offenderCount==0. Ez index.
|
||||||
@ -112,28 +132,28 @@ class GuardLine {
|
|||||||
else{
|
else{
|
||||||
// fallback mode is a bit different
|
// fallback mode is a bit different
|
||||||
edge_upper = 0;
|
edge_upper = 0;
|
||||||
edge_lower = this.conf.canvas.height - 1;
|
edge_lower = this.aard.canvas.height - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rowStart, rowEnd;
|
var rowStart, rowEnd;
|
||||||
|
|
||||||
// <<<=======| checking upper row |========>>>
|
// <<<=======| checking upper row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_upper * this.conf.canvas.width) << 2) + offset;
|
rowStart = ((edge_upper * this.aard.canvas.width) << 2) + offset;
|
||||||
rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
rowEnd = rowStart + ( this.aard.canvas.width << 2 ) - (offset * 2);
|
||||||
|
|
||||||
if (Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine) {
|
if (Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine) {
|
||||||
offenderCount = this._gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
// offenderCount = this._gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
||||||
} else {
|
} else {
|
||||||
offenderCount = this._gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
offenderCount = this._gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
||||||
}
|
}
|
||||||
// <<<=======| checking lower row |========>>>
|
// <<<=======| checking lower row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_lower * this.conf.canvas.width) << 2) + offset;
|
rowStart = ((edge_lower * this.aard.canvas.width) << 2) + offset;
|
||||||
rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
rowEnd = rowStart + ( this.aard.canvas.width << 2 ) - (offset * 2);
|
||||||
|
|
||||||
if (Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine) {
|
if (Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine) {
|
||||||
offenderCount = this._gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
// offenderCount = this._gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
||||||
} else {
|
} else {
|
||||||
offenderCount = this._gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
offenderCount = this._gl_rowCheck(image, rowStart, rowEnd, offenders, offenderCount);
|
||||||
}
|
}
|
||||||
@ -156,11 +176,11 @@ class GuardLine {
|
|||||||
return {success: false, offenders: ret};
|
return {success: false, offenders: ret};
|
||||||
}
|
}
|
||||||
|
|
||||||
imageCheck(image){
|
imageCheck(image, fallbackMode?: boolean): ImageCheckResult {
|
||||||
if(!this.imageBar.top || !this.imageBar.bottom)
|
if(!this.imageBar.top || !this.imageBar.bottom)
|
||||||
return { success: false };
|
return { success: false };
|
||||||
|
|
||||||
var offset = (this.conf.canvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
var offset = (this.aard.canvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
||||||
|
|
||||||
// TODO: implement logo check.
|
// TODO: implement logo check.
|
||||||
|
|
||||||
@ -181,35 +201,35 @@ class GuardLine {
|
|||||||
// robu (eden izmed robov je lahko v celoti črn)
|
// 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
|
// 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)
|
// on one edge (one of the edges can be black as long as both aren't)
|
||||||
var successThreshold = (this.conf.canvas.width * this.settings.active.arDetect.guardLine.imageTestThreshold);
|
var successThreshold = (this.aard.canvas.width * this.settings.active.arDetect.guardLine.imageTestThreshold);
|
||||||
var rowStart, rowEnd;
|
var rowStart, rowEnd;
|
||||||
|
|
||||||
|
|
||||||
// <<<=======| checking upper row |========>>>
|
// <<<=======| checking upper row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_upper * this.conf.canvas.width) << 2) + offset;
|
rowStart = ((edge_upper * this.aard.canvas.width) << 2) + offset;
|
||||||
rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
rowEnd = rowStart + ( this.aard.canvas.width << 2 ) - (offset * 2);
|
||||||
|
|
||||||
var res = false;
|
var res = false;
|
||||||
|
|
||||||
if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){
|
if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){
|
||||||
res = this._ti_debugCheckRow(image, rowStart, rowEnd, successThreshold);
|
// res = this._ti_debugCheckRow(image, rowStart, rowEnd, successThreshold);
|
||||||
} else {
|
} else {
|
||||||
res = this._ti_checkRow(image, rowStart, rowEnd,successThreshold);
|
res = this._ti_checkRow(image, rowStart, rowEnd,successThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(res)
|
if (res) {
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
}
|
||||||
|
|
||||||
// <<<=======| checking lower row |========>>>
|
// <<<=======| checking lower row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_lower * this.conf.canvas.width) << 2) + offset;
|
rowStart = ((edge_lower * this.aard.canvas.width) << 2) + offset;
|
||||||
// rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
// rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
||||||
|
|
||||||
|
|
||||||
if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){
|
if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){
|
||||||
res = this._ti_debugCheckRow(image, rowStart, rowEnd, successThreshold);
|
// res = this._ti_debugCheckRow(image, rowStart, rowEnd, successThreshold);
|
||||||
} else {
|
} else {
|
||||||
res = this._ti_checkRow(image, rowStart, rowEnd,successThreshold);
|
res = this._ti_checkRow(image, rowStart, rowEnd,successThreshold);
|
||||||
}
|
}
|
||||||
@ -246,35 +266,35 @@ class GuardLine {
|
|||||||
return offenderCount;
|
return offenderCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount){
|
// _gl_debugRowCheck(image, rowStart, rowEnd, offenders, offenderCount){
|
||||||
var firstOffender = -1;
|
// var firstOffender = -1;
|
||||||
for(var i = rowStart; i < rowEnd; i+=4){
|
// 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
|
// // we track sections that go over what's supposed to be a black line, so we can suggest more
|
||||||
// columns to sample
|
// // columns to sample
|
||||||
if(image[i] > this.blackbarThreshold || image[i+1] > this.blackbarThreshold || image[i+2] > this.blackbarThreshold){
|
// if(image[i] > this.blackbarThreshold || image[i+1] > this.blackbarThreshold || image[i+2] > this.blackbarThreshold){
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.VIOLATION);
|
// this.aard.debugCanvas.trace(i, DebugCanvasClasses.VIOLATION);
|
||||||
if(firstOffender < 0){
|
// if(firstOffender < 0){
|
||||||
firstOffender = (i - rowStart) >> 2;
|
// firstOffender = (i - rowStart) >> 2;
|
||||||
offenderCount++;
|
// offenderCount++;
|
||||||
offenders.push({x: firstOffender, width: 1});
|
// offenders.push({x: firstOffender, width: 1});
|
||||||
}
|
// }
|
||||||
else{
|
// else{
|
||||||
offenders[offenderCount].width++
|
// offenders[offenderCount].width++
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else{
|
// else{
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.GUARDLINE_BLACKBAR);
|
// this.aard.debugCanvas.trace(i, DebugCanvasClasses.GUARDLINE_BLACKBAR);
|
||||||
// is that a black pixel again? Let's reset the 'first offender'
|
// // is that a black pixel again? Let's reset the 'first offender'
|
||||||
firstOffender = -1;
|
// firstOffender = -1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
return offenderCount;
|
// return offenderCount;
|
||||||
}
|
// }
|
||||||
|
|
||||||
_ti_checkRow(image, rowStart, rowEnd, successThreshold) {
|
_ti_checkRow(image, rowStart, rowEnd, successThreshold): boolean {
|
||||||
for(var i = rowStart; i < rowEnd; i+=4){
|
for(var i = rowStart; i < rowEnd; i+=4){
|
||||||
if(image[i] > this.imageThreshold || image[i+1] > this.imageThreshold || image[i+2] > this.imageThreshold){
|
if(image[i] > this.imageThreshold || image[i+1] > this.imageThreshold || image[i+2] > this.imageThreshold){
|
||||||
if(successThreshold --<= 0){
|
if(successThreshold --<= 0){
|
||||||
@ -286,20 +306,20 @@ class GuardLine {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ti_debugCheckRow(image, rowStart, rowEnd, successThreshold) {
|
// _ti_debugCheckRow(image, rowStart, rowEnd, successThreshold) {
|
||||||
for(var i = rowStart; i < rowEnd; i+=4){
|
// for(var i = rowStart; i < rowEnd; i+=4){
|
||||||
if(image[i] > this.imageThreshold || image[i+1] > this.imageThreshold || image[i+2] > this.imageThreshold){
|
// if(image[i] > this.imageThreshold || image[i+1] > this.imageThreshold || image[i+2] > this.imageThreshold){
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.GUARDLINE_IMAGE);
|
// this.aard.debugCanvas.trace(i, DebugCanvasClasses.GUARDLINE_IMAGE);
|
||||||
if(successThreshold --<= 0){
|
// if(successThreshold --<= 0){
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.WARN);
|
// this.aard.debugCanvas.trace(i, DebugCanvasClasses.WARN);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GuardLine;
|
export default GuardLine;
|
@ -3,12 +3,27 @@ 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';
|
||||||
import AntiGradientMode from '../../../../common/enums/AntiGradientMode.enum';
|
import AntiGradientMode from '../../../../common/enums/AntiGradientMode.enum';
|
||||||
|
import ArDetector from '../ArDetector';
|
||||||
|
import Logger from '../../Logger';
|
||||||
|
import Settings from '../../Settings';
|
||||||
|
|
||||||
if (Debug.debug) {
|
if (Debug.debug) {
|
||||||
console.log("Loading EdgeDetect.js");
|
console.log("Loading EdgeDetect.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
class EdgeDetect{
|
class EdgeDetect{
|
||||||
|
conf: ArDetector;
|
||||||
|
logger: Logger;
|
||||||
|
settings: Settings;
|
||||||
|
|
||||||
|
|
||||||
|
// helper stuff
|
||||||
|
private sampleWidthBase: number;
|
||||||
|
private halfSample: number;
|
||||||
|
private detectionThreshold: number;
|
||||||
|
private colsThreshold: number;
|
||||||
|
private blackbarThreshold: number;
|
||||||
|
private imageThreshold: number;
|
||||||
|
|
||||||
constructor(ardConf){
|
constructor(ardConf){
|
||||||
this.conf = ardConf;
|
this.conf = ardConf;
|
||||||
@ -41,7 +56,7 @@ class EdgeDetect{
|
|||||||
// edges = fastCandidates; // todo: processing
|
// edges = fastCandidates; // todo: processing
|
||||||
// } else {
|
// } else {
|
||||||
edgeCandidates = this.edgeDetect(image, fastCandidates);
|
edgeCandidates = this.edgeDetect(image, fastCandidates);
|
||||||
bars = this.edgePostprocess(edgeCandidates, this.conf.canvas.height);
|
bars = this.edgePostprocess(edgeCandidates);
|
||||||
// }
|
// }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.log('error', 'arDetect', '%c[EdgeDetect::findBars] find bars failed.', 'background: #f00, color: #000', e);
|
this.logger.log('error', 'arDetect', '%c[EdgeDetect::findBars] find bars failed.', 'background: #f00, color: #000', e);
|
||||||
@ -259,7 +274,7 @@ class EdgeDetect{
|
|||||||
loopEnd = sampleRow_black + sampleEnd;
|
loopEnd = sampleRow_black + sampleEnd;
|
||||||
|
|
||||||
if (Debug.debugCanvas.enabled){
|
if (Debug.debugCanvas.enabled){
|
||||||
blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd);
|
// blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd);
|
||||||
} else {
|
} else {
|
||||||
blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd);
|
blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd);
|
||||||
}
|
}
|
||||||
@ -274,7 +289,7 @@ class EdgeDetect{
|
|||||||
loopEnd = sampleRow_color + sampleEnd;
|
loopEnd = sampleRow_color + sampleEnd;
|
||||||
|
|
||||||
if (Debug.debugCanvas.enabled) {
|
if (Debug.debugCanvas.enabled) {
|
||||||
this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop)
|
// this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop)
|
||||||
} else {
|
} else {
|
||||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop);
|
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop);
|
||||||
}
|
}
|
||||||
@ -302,7 +317,7 @@ class EdgeDetect{
|
|||||||
loopEnd = sampleRow_black + sampleEnd;
|
loopEnd = sampleRow_black + sampleEnd;
|
||||||
|
|
||||||
if(Debug.debugCanvas.enabled){
|
if(Debug.debugCanvas.enabled){
|
||||||
blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd);
|
// blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd);
|
||||||
} else {
|
} else {
|
||||||
blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd);
|
blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd);
|
||||||
}
|
}
|
||||||
@ -317,7 +332,7 @@ class EdgeDetect{
|
|||||||
loopEnd = sampleRow_color + sampleEnd;
|
loopEnd = sampleRow_color + sampleEnd;
|
||||||
|
|
||||||
if(Debug.debugCanvas.enabled) {
|
if(Debug.debugCanvas.enabled) {
|
||||||
this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom);
|
// this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom);
|
||||||
} else {
|
} else {
|
||||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom);
|
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom);
|
||||||
}
|
}
|
||||||
@ -1095,62 +1110,62 @@ class EdgeDetect{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_columnTest_dbgc(image, top, bottom, colsIn, colsOut, reverseSearchDirection){
|
// _columnTest_dbgc(image, top, bottom, colsIn, colsOut, reverseSearchDirection){
|
||||||
var tmpI;
|
// var tmpI;
|
||||||
if(reverseSearchDirection){
|
// if(reverseSearchDirection){
|
||||||
for(var i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){
|
// for(var i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){
|
||||||
for(var col of colsIn){
|
// for(var col of colsIn){
|
||||||
tmpI = i + (col << 2);
|
// tmpI = i + (col << 2);
|
||||||
|
|
||||||
if( image[tmpI] > this.blackbarThreshold ||
|
// if( image[tmpI] > this.blackbarThreshold ||
|
||||||
image[tmpI + 1] > this.blackbarThreshold ||
|
// image[tmpI + 1] > this.blackbarThreshold ||
|
||||||
image[tmpI + 2] > this.blackbarThreshold ){
|
// image[tmpI + 2] > this.blackbarThreshold ){
|
||||||
|
|
||||||
var bottom = (i / this.conf.canvasImageDataRowLength) + 1;
|
// var bottom = (i / this.conf.canvasImageDataRowLength) + 1;
|
||||||
colsOut.push({
|
// colsOut.push({
|
||||||
col: col,
|
// col: col,
|
||||||
bottom: bottom
|
// bottom: bottom
|
||||||
});
|
// });
|
||||||
colsIn.splice(colsIn.indexOf(col), 1);
|
// colsIn.splice(colsIn.indexOf(col), 1);
|
||||||
this.conf.debugCanvas.trace(tmpI,DebugCanvasClasses.EDGEDETECT_CANDIDATE);
|
// this.conf.debugCanvas.trace(tmpI,DebugCanvasClasses.EDGEDETECT_CANDIDATE);
|
||||||
}
|
// }
|
||||||
else{
|
// else{
|
||||||
this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_ONBLACK);
|
// this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_ONBLACK);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if(colsIn.length < this.colsThreshold)
|
// if(colsIn.length < this.colsThreshold)
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
for(var i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){
|
// for(var i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){
|
||||||
for(var col of colsIn){
|
// for(var col of colsIn){
|
||||||
tmpI = i + (col << 2);
|
// tmpI = i + (col << 2);
|
||||||
|
|
||||||
if( image[tmpI] > this.blackbarThreshold ||
|
// if( image[tmpI] > this.blackbarThreshold ||
|
||||||
image[tmpI + 1] > this.blackbarThreshold ||
|
// image[tmpI + 1] > this.blackbarThreshold ||
|
||||||
image[tmpI + 2] > this.blackbarThreshold ){
|
// image[tmpI + 2] > this.blackbarThreshold ){
|
||||||
|
|
||||||
colsOut.push({
|
// colsOut.push({
|
||||||
col: col,
|
// col: col,
|
||||||
top: (i / this.conf.canvasImageDataRowLength) - 1
|
// top: (i / this.conf.canvasImageDataRowLength) - 1
|
||||||
});
|
// });
|
||||||
colsIn.splice(colsIn.indexOf(col), 1);
|
// colsIn.splice(colsIn.indexOf(col), 1);
|
||||||
this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_CANDIDATE);
|
// this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_CANDIDATE);
|
||||||
if(tmpI-1 > 0){
|
// if(tmpI-1 > 0){
|
||||||
this.conf.debugCanvas.trace(tmpI - 1, DebugCanvasClasses.EDGEDETECT_CANDIDATE_SECONDARY);
|
// this.conf.debugCanvas.trace(tmpI - 1, DebugCanvasClasses.EDGEDETECT_CANDIDATE_SECONDARY);
|
||||||
}
|
// }
|
||||||
if(tmpI+1 < image.length){
|
// if(tmpI+1 < image.length){
|
||||||
this.conf.debugCanvas.trace(tmpI + 1, DebugCanvasClasses.EDGEDETECT_CANDIDATE_SECONDARY);
|
// this.conf.debugCanvas.trace(tmpI + 1, DebugCanvasClasses.EDGEDETECT_CANDIDATE_SECONDARY);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_ONBLACK);
|
// this.conf.debugCanvas.trace(tmpI, DebugCanvasClasses.EDGEDETECT_ONBLACK);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if(colsIn.length < this.colsThreshold)
|
// if(colsIn.length < this.colsThreshold)
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
_blackbarTest(image, start, end){
|
_blackbarTest(image, start, end){
|
||||||
for(var i = start; i < end; i += 4){
|
for(var i = start; i < end; i += 4){
|
||||||
@ -1163,20 +1178,20 @@ class EdgeDetect{
|
|||||||
return false; // no violation
|
return false; // no violation
|
||||||
}
|
}
|
||||||
|
|
||||||
_blackbarTest_dbg(image, start, end){
|
// _blackbarTest_dbg(image, start, end){
|
||||||
for(var i = start; i < end; i += 4){
|
// for(var i = start; i < end; i += 4){
|
||||||
if( image[i ] > this.blackbarThreshold ||
|
// if( image[i ] > this.blackbarThreshold ||
|
||||||
image[i+1] > this.blackbarThreshold ||
|
// image[i+1] > this.blackbarThreshold ||
|
||||||
image[i+2] > this.blackbarThreshold ){
|
// image[i+2] > this.blackbarThreshold ){
|
||||||
|
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.VIOLATION)
|
// this.conf.debugCanvas.trace(i, DebugCanvasClasses.VIOLATION)
|
||||||
return true;
|
// return true;
|
||||||
} else {
|
// } else {
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.EDGEDETECT_BLACKBAR)
|
// this.conf.debugCanvas.trace(i, DebugCanvasClasses.EDGEDETECT_BLACKBAR)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return false; // no violation
|
// return false; // no violation
|
||||||
}
|
// }
|
||||||
|
|
||||||
_imageTest(image, start, end, sampleOffset, edgeCandidates){
|
_imageTest(image, start, end, sampleOffset, edgeCandidates){
|
||||||
var detections = 0;
|
var detections = 0;
|
||||||
@ -1198,28 +1213,28 @@ class EdgeDetect{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_imageTest_dbg(image, start, end, sampleOffset, edgeCandidates){
|
// _imageTest_dbg(image, start, end, sampleOffset, edgeCandidates){
|
||||||
var detections = 0;
|
// var detections = 0;
|
||||||
|
|
||||||
for(var i = start; i < end; i += 4){
|
// for(var i = start; i < end; i += 4){
|
||||||
if( image[i ] > this.blackbarThreshold ||
|
// if( image[i ] > this.blackbarThreshold ||
|
||||||
image[i+1] > this.blackbarThreshold ||
|
// image[i+1] > this.blackbarThreshold ||
|
||||||
image[i+2] > this.blackbarThreshold ){
|
// image[i+2] > this.blackbarThreshold ){
|
||||||
++detections;
|
// ++detections;
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.EDGEDETECT_IMAGE);
|
// this.conf.debugCanvas.trace(i, DebugCanvasClasses.EDGEDETECT_IMAGE);
|
||||||
} else {
|
// } else {
|
||||||
this.conf.debugCanvas.trace(i, DebugCanvasClasses.WARN);
|
// this.conf.debugCanvas.trace(i, DebugCanvasClasses.WARN);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if(detections >= this.detectionThreshold){
|
// if(detections >= this.detectionThreshold){
|
||||||
if(edgeCandidates[sampleOffset] != undefined)
|
// if(edgeCandidates[sampleOffset] != undefined)
|
||||||
edgeCandidates[sampleOffset].count++;
|
// edgeCandidates[sampleOffset].count++;
|
||||||
else{
|
// else{
|
||||||
edgeCandidates[sampleOffset] = {offset: sampleOffset, count: 1};
|
// edgeCandidates[sampleOffset] = {offset: sampleOffset, count: 1};
|
||||||
edgeCandidates.count++;
|
// edgeCandidates.count++;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user