Switch to gl canvas
This commit is contained in:
parent
e56d32180c
commit
de78f8b1d5
@ -82,6 +82,12 @@ export class GlCanvas {
|
|||||||
private programInfo: GlCanvasProgramInfo;
|
private programInfo: GlCanvasProgramInfo;
|
||||||
private projectionMatrix: mat4;
|
private projectionMatrix: mat4;
|
||||||
|
|
||||||
|
get width() {
|
||||||
|
return this.canvas.width;
|
||||||
|
}
|
||||||
|
get height() {
|
||||||
|
return this.canvas.height;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(options: GlCanvasOptions) {
|
constructor(options: GlCanvasOptions) {
|
||||||
this.canvas = document.createElement('canvas');
|
this.canvas = document.createElement('canvas');
|
||||||
@ -117,6 +123,18 @@ export class GlCanvas {
|
|||||||
return this.frameBuffer;
|
return this.frameBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up after itself
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
this.gl.deleteProgram(this.programInfo.program);
|
||||||
|
this.gl.deleteBuffer(this.buffers.position);
|
||||||
|
this.gl.deleteBuffer(this.buffers.normal);
|
||||||
|
this.gl.deleteBuffer(this.buffers.textureCoord);
|
||||||
|
this.gl.deleteBuffer(this.buffers.indices);
|
||||||
|
this.gl.deleteTexture(this.texture);
|
||||||
|
}
|
||||||
|
|
||||||
private initWebgl() {
|
private initWebgl() {
|
||||||
// Initialize the GL context
|
// Initialize the GL context
|
||||||
this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
|
@ -14,6 +14,7 @@ import Logger from '../Logger';
|
|||||||
import VideoData from '../video-data/VideoData';
|
import VideoData from '../video-data/VideoData';
|
||||||
import Settings from '../Settings';
|
import Settings from '../Settings';
|
||||||
import EventBus from '../EventBus';
|
import EventBus from '../EventBus';
|
||||||
|
import { GlCanvas } from '../aard/gl/GlCanvas';
|
||||||
|
|
||||||
enum VideoPlaybackState {
|
enum VideoPlaybackState {
|
||||||
Playing,
|
Playing,
|
||||||
@ -82,11 +83,10 @@ class ArDetector {
|
|||||||
_nextTick: boolean;
|
_nextTick: boolean;
|
||||||
|
|
||||||
private animationFrameHandle: any;
|
private animationFrameHandle: any;
|
||||||
private attachedCanvas: HTMLCanvasElement;
|
|
||||||
canvas: HTMLCanvasElement;
|
|
||||||
private context: CanvasRenderingContext2D;
|
|
||||||
canvasImageDataRowLength: number;
|
canvasImageDataRowLength: number;
|
||||||
|
|
||||||
|
glCanvas: GlCanvas;
|
||||||
|
|
||||||
private timers = {
|
private timers = {
|
||||||
nextFrameCheckTime: Date.now()
|
nextFrameCheckTime: Date.now()
|
||||||
}
|
}
|
||||||
@ -189,43 +189,24 @@ class ArDetector {
|
|||||||
//
|
//
|
||||||
// [1] initiate canvases
|
// [1] initiate canvases
|
||||||
//
|
//
|
||||||
|
if (this.glCanvas) {
|
||||||
if (!cwidth) {
|
this.glCanvas.destroy();
|
||||||
cwidth = this.settings.active.arDetect.canvasDimensions.sampleCanvas.width;
|
|
||||||
cheight = this.settings.active.arDetect.canvasDimensions.sampleCanvas.height;
|
|
||||||
}
|
}
|
||||||
|
this.glCanvas = new GlCanvas(this.settings.active.arDetect.canvasDimensions.sampleCanvas);
|
||||||
if (this.canvas) {
|
|
||||||
this.canvas.remove();
|
|
||||||
}
|
|
||||||
// if (this.blackframeCanvas) {
|
|
||||||
// this.blackframeCanvas.remove();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// things to note: we'll be keeping canvas in memory only.
|
|
||||||
this.canvas = document.createElement("canvas");
|
|
||||||
this.canvas.width = cwidth;
|
|
||||||
this.canvas.height = cheight;
|
|
||||||
// this.blackframeCanvas = document.createElement("canvas");
|
|
||||||
// this.blackframeCanvas.width = this.settings.active.arDetect.canvasDimensions.blackframeCanvas.width;
|
|
||||||
// this.blackframeCanvas.height = this.settings.active.arDetect.canvasDimensions.blackframeCanvas.height;
|
|
||||||
|
|
||||||
this.context = this.canvas.getContext("2d");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// [2] determine places we'll use to sample our main frame
|
// [2] determine places we'll use to sample our main frame
|
||||||
//
|
//
|
||||||
|
|
||||||
let ncol = this.settings.active.arDetect.sampling.staticCols;
|
let ncol = this.settings.active.arDetect.sampling.staticCols;
|
||||||
let nrow = this.settings.active.arDetect.sampling.staticRows;
|
let nrow = this.settings.active.arDetect.sampling.staticRows;
|
||||||
|
|
||||||
let colSpacing = this.canvas.width / ncol;
|
let colSpacing = this.glCanvas.width / ncol;
|
||||||
let rowSpacing = (this.canvas.height << 2) / nrow;
|
let rowSpacing = (this.glCanvas.height << 2) / nrow;
|
||||||
|
|
||||||
this.sampleLines = [];
|
this.sampleLines = [];
|
||||||
this.sampleCols = [];
|
this.sampleCols = [];
|
||||||
|
|
||||||
for(let i = 0; i < ncol; i++){
|
for (let i = 0; i < ncol; i++){
|
||||||
if(i < ncol - 1)
|
if(i < ncol - 1)
|
||||||
this.sampleCols.push(Math.round(colSpacing * i));
|
this.sampleCols.push(Math.round(colSpacing * i));
|
||||||
else{
|
else{
|
||||||
@ -233,7 +214,7 @@ class ArDetector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let i = 0; i < nrow; i++){
|
for (let i = 0; i < nrow; i++){
|
||||||
if(i < ncol - 5)
|
if(i < ncol - 5)
|
||||||
this.sampleLines.push(Math.round(rowSpacing * i));
|
this.sampleLines.push(Math.round(rowSpacing * i));
|
||||||
else{
|
else{
|
||||||
@ -244,7 +225,6 @@ class ArDetector {
|
|||||||
//
|
//
|
||||||
// [3] do other things setup needs to do
|
// [3] do other things setup needs to do
|
||||||
//
|
//
|
||||||
|
|
||||||
this.resetBlackLevel();
|
this.resetBlackLevel();
|
||||||
|
|
||||||
// if we're restarting ArDetect, we need to do this in order to force-recalculate aspect ratio
|
// if we're restarting ArDetect, we need to do this in order to force-recalculate aspect ratio
|
||||||
@ -253,11 +233,10 @@ class ArDetector {
|
|||||||
this.canvasImageDataRowLength = cwidth << 2;
|
this.canvasImageDataRowLength = cwidth << 2;
|
||||||
|
|
||||||
this.start();
|
this.start();
|
||||||
|
// if(Debug.debugCanvas.enabled){
|
||||||
if(Debug.debugCanvas.enabled){
|
|
||||||
// this.debugCanvas.init({width: cwidth, height: cheight});
|
// this.debugCanvas.init({width: cwidth, height: cheight});
|
||||||
// DebugCanvas.draw("test marker","test","rect", {x:5, y:5}, {width: 5, height: 5});
|
// DebugCanvas.draw("test marker","test","rect", {x:5, y:5}, {width: 5, height: 5});
|
||||||
}
|
// }
|
||||||
|
|
||||||
this.conf.arSetupComplete = true;
|
this.conf.arSetupComplete = true;
|
||||||
}
|
}
|
||||||
@ -391,20 +370,6 @@ class ArDetector {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private attachCanvas(canvas){
|
|
||||||
if(this.attachedCanvas)
|
|
||||||
this.attachedCanvas.remove();
|
|
||||||
|
|
||||||
// todo: place canvas on top of the video instead of random location
|
|
||||||
canvas.style.position = "absolute";
|
|
||||||
canvas.style.left = "200px";
|
|
||||||
canvas.style.top = "1200px";
|
|
||||||
canvas.style.zIndex = 10000;
|
|
||||||
|
|
||||||
document.getElementsByTagName("body")[0]
|
|
||||||
.appendChild(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds execution time sample for performance metrics
|
* Adds execution time sample for performance metrics
|
||||||
* @param performanceObject
|
* @param performanceObject
|
||||||
@ -749,19 +714,19 @@ class ArDetector {
|
|||||||
// aspect ratio and correct our calculations to account for that
|
// aspect ratio and correct our calculations to account for that
|
||||||
|
|
||||||
const fileAr = this.video.videoWidth / this.video.videoHeight;
|
const fileAr = this.video.videoWidth / this.video.videoHeight;
|
||||||
const canvasAr = this.canvas.width / this.canvas.height;
|
const canvasAr = this.glCanvas.width / this.glCanvas.height;
|
||||||
let widthCorrected;
|
let widthCorrected;
|
||||||
|
|
||||||
if (edges.top && edges.bottom) {
|
if (edges.top && edges.bottom) {
|
||||||
// in case of letterbox, we take canvas height as canon and assume width got stretched or squished
|
// in case of letterbox, we take canvas height as canon and assume width got stretched or squished
|
||||||
|
|
||||||
if (fileAr != canvasAr) {
|
if (fileAr != canvasAr) {
|
||||||
widthCorrected = this.canvas.height * fileAr;
|
widthCorrected = this.glCanvas.height * fileAr;
|
||||||
} else {
|
} else {
|
||||||
widthCorrected = this.canvas.width;
|
widthCorrected = this.glCanvas.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
return widthCorrected / (this.canvas.height - letterbox);
|
return widthCorrected / (this.glCanvas.height - letterbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,22 +787,19 @@ class ArDetector {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.context) {
|
if (!this.glCanvas) {
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
let sampleCols = this.sampleCols.slice(0);
|
let sampleCols = this.sampleCols.slice(0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let startTime = performance.now();
|
let startTime = performance.now();
|
||||||
await new Promise<void>(
|
const imageData = await new Promise<Uint8Array>(
|
||||||
resolve => {
|
resolve => {
|
||||||
this.context.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
|
this.glCanvas.drawVideoFrame(this.video);
|
||||||
resolve();
|
resolve(this.glCanvas.getImageData());
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const imageData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height).data;
|
|
||||||
timerResults.imageDrawTime = performance.now() - startTime;
|
timerResults.imageDrawTime = performance.now() - startTime;
|
||||||
|
|
||||||
startTime = performance.now();
|
startTime = performance.now();
|
||||||
@ -1130,7 +1092,7 @@ class ArDetector {
|
|||||||
// returns 'false' if we found a non-black edge pixel.
|
// returns 'false' if we found a non-black edge pixel.
|
||||||
|
|
||||||
// If we detect anything darker than blackLevel, we modify blackLevel to the new lowest value
|
// If we detect anything darker than blackLevel, we modify blackLevel to the new lowest value
|
||||||
const rowOffset = this.canvas.width * (this.canvas.height - 1);
|
const rowOffset = this.glCanvas.width * (this.glCanvas.height - 1);
|
||||||
let currentMin = 255, currentMax = 0, colOffset_r, colOffset_g, colOffset_b, colOffset_rb, colOffset_gb, colOffset_bb, blthreshold = this.settings.active.arDetect.blackbar.threshold;
|
let currentMin = 255, currentMax = 0, colOffset_r, colOffset_g, colOffset_b, colOffset_rb, colOffset_gb, colOffset_bb, blthreshold = this.settings.active.arDetect.blackbar.threshold;
|
||||||
|
|
||||||
// detect black level. if currentMax comes above blackbar + blackbar threshold, we know we aren't letterboxed
|
// detect black level. if currentMax comes above blackbar + blackbar threshold, we know we aren't letterboxed
|
||||||
|
@ -42,7 +42,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.aard.canvas.height ){
|
if (bbTop < 0 || bbBottom >= this.aard.glCanvas.height ){
|
||||||
throw {error: "INVALID_SETTINGS_IN_GUARDLINE", bbTop, bbBottom}
|
throw {error: "INVALID_SETTINGS_IN_GUARDLINE", bbTop, bbBottom}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ class GuardLine {
|
|||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
let offset = (this.aard.canvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
let offset = (this.aard.glCanvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
||||||
|
|
||||||
let offenders = [];
|
let offenders = [];
|
||||||
let offenderCount = -1; // doing it this way means first offender has offenderCount==0. Ez index.
|
let offenderCount = -1; // doing it this way means first offender has offenderCount==0. Ez index.
|
||||||
@ -117,8 +117,8 @@ class GuardLine {
|
|||||||
|
|
||||||
// <<<=======| checking upper row |========>>>
|
// <<<=======| checking upper row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_upper * this.aard.canvas.width) << 2) + offset;
|
rowStart = ((edge_upper * this.aard.glCanvas.width) << 2) + offset;
|
||||||
rowEnd = rowStart + ( this.aard.canvas.width << 2 ) - (offset * 2);
|
rowEnd = rowStart + ( this.aard.glCanvas.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);
|
||||||
@ -127,8 +127,8 @@ class GuardLine {
|
|||||||
}
|
}
|
||||||
// <<<=======| checking lower row |========>>>
|
// <<<=======| checking lower row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_lower * this.aard.canvas.width) << 2) + offset;
|
rowStart = ((edge_lower * this.aard.glCanvas.width) << 2) + offset;
|
||||||
rowEnd = rowStart + ( this.aard.canvas.width << 2 ) - (offset * 2);
|
rowEnd = rowStart + ( this.aard.glCanvas.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);
|
||||||
@ -158,7 +158,7 @@ class GuardLine {
|
|||||||
if(!this.imageBar.top || !this.imageBar.bottom)
|
if(!this.imageBar.top || !this.imageBar.bottom)
|
||||||
return { success: false };
|
return { success: false };
|
||||||
|
|
||||||
let offset = (this.aard.canvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
let offset = (this.aard.glCanvas.width * this.settings.active.arDetect.guardLine.ignoreEdgeMargin) << 2;
|
||||||
|
|
||||||
// TODO: implement logo check.
|
// TODO: implement logo check.
|
||||||
|
|
||||||
@ -167,14 +167,14 @@ class GuardLine {
|
|||||||
|
|
||||||
// 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)
|
||||||
let successThreshold = (this.aard.canvas.width * this.settings.active.arDetect.guardLine.imageTestThreshold);
|
let successThreshold = (this.aard.glCanvas.width * this.settings.active.arDetect.guardLine.imageTestThreshold);
|
||||||
let rowStart, rowEnd;
|
let rowStart, rowEnd;
|
||||||
|
|
||||||
|
|
||||||
// <<<=======| checking upper row |========>>>
|
// <<<=======| checking upper row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_upper * this.aard.canvas.width) << 2) + offset;
|
rowStart = ((edge_upper * this.aard.glCanvas.width) << 2) + offset;
|
||||||
rowEnd = rowStart + ( this.aard.canvas.width << 2 ) - (offset * 2);
|
rowEnd = rowStart + ( this.aard.glCanvas.width << 2 ) - (offset * 2);
|
||||||
|
|
||||||
let res = false;
|
let res = false;
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ class GuardLine {
|
|||||||
|
|
||||||
// <<<=======| checking lower row |========>>>
|
// <<<=======| checking lower row |========>>>
|
||||||
|
|
||||||
rowStart = ((edge_lower * this.aard.canvas.width) << 2) + offset;
|
rowStart = ((edge_lower * this.aard.glCanvas.width) << 2) + offset;
|
||||||
// rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
// rowEnd = rowStart + ( this.conf.canvas.width << 2 ) - (offset * 2);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import Debug from '../../../conf/Debug';
|
|||||||
import EdgeStatus from './enums/EdgeStatusEnum';
|
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 ArDetector from '../ArDetector';
|
||||||
import Logger from '../../Logger';
|
import Logger from '../../Logger';
|
||||||
import Settings from '../../Settings';
|
import Settings from '../../Settings';
|
||||||
@ -31,7 +31,7 @@ class EdgeDetect{
|
|||||||
this.settings = ardConf.settings;
|
this.settings = ardConf.settings;
|
||||||
|
|
||||||
this.sampleWidthBase = this.settings.active.arDetect.edgeDetection.sampleWidth << 2; // corrected so we can work on imageData
|
this.sampleWidthBase = this.settings.active.arDetect.edgeDetection.sampleWidth << 2; // corrected so we can work on imageData
|
||||||
this.halfSample = this.sampleWidthBase >> 1;
|
this.halfSample = this.sampleWidthBase >> 1;
|
||||||
|
|
||||||
this.detectionThreshold = this.settings.active.arDetect.edgeDetection.detectionThreshold;
|
this.detectionThreshold = this.settings.active.arDetect.edgeDetection.detectionThreshold;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class EdgeDetect{
|
|||||||
|
|
||||||
// initiates things that we may have to change later down the line
|
// initiates things that we may have to change later down the line
|
||||||
init() {
|
init() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findBars(image, sampleCols, direction = EdgeDetectPrimaryDirection.Vertical, quality = EdgeDetectQuality.Improved, guardLineOut?, blackFrameAnalysis?){
|
findBars(image, sampleCols, direction = EdgeDetectPrimaryDirection.Vertical, quality = EdgeDetectQuality.Improved, guardLineOut?, blackFrameAnalysis?){
|
||||||
@ -48,7 +48,7 @@ class EdgeDetect{
|
|||||||
if (direction == EdgeDetectPrimaryDirection.Vertical) {
|
if (direction == EdgeDetectPrimaryDirection.Vertical) {
|
||||||
try {
|
try {
|
||||||
fastCandidates = this.findCandidates(image, sampleCols, guardLineOut);
|
fastCandidates = this.findCandidates(image, sampleCols, guardLineOut);
|
||||||
|
|
||||||
if (! this.isValidSample(fastCandidates)) {
|
if (! this.isValidSample(fastCandidates)) {
|
||||||
return {status: EdgeStatus.ARUnknown};
|
return {status: EdgeStatus.ARUnknown};
|
||||||
}
|
}
|
||||||
@ -67,17 +67,17 @@ class EdgeDetect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return bars;
|
return bars;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findCandidates(image, sampleCols, guardLineOut){
|
findCandidates(image, sampleCols, guardLineOut){
|
||||||
try {
|
try {
|
||||||
let upper_top, upper_bottom, lower_top, lower_bottom;
|
let upper_top, upper_bottom, lower_top, lower_bottom;
|
||||||
|
|
||||||
// const cols_a = sampleCols.slice(0);
|
// const cols_a = sampleCols.slice(0);
|
||||||
const cols_a = new Array(sampleCols.length);
|
const cols_a = new Array(sampleCols.length);
|
||||||
const res_top = [];
|
const res_top = [];
|
||||||
|
|
||||||
for (let i = 0; i < cols_a.length; i++) {
|
for (let i = 0; i < cols_a.length; i++) {
|
||||||
cols_a[i] = {
|
cols_a[i] = {
|
||||||
id: i,
|
id: i,
|
||||||
@ -87,52 +87,52 @@ class EdgeDetect{
|
|||||||
|
|
||||||
const cols_b = cols_a.slice(0);
|
const cols_b = cols_a.slice(0);
|
||||||
const res_bottom = [];
|
const res_bottom = [];
|
||||||
|
|
||||||
this.colsThreshold = sampleCols.length * this.settings.active.arDetect.edgeDetection.minColsForSearch;
|
this.colsThreshold = sampleCols.length * this.settings.active.arDetect.edgeDetection.minColsForSearch;
|
||||||
if (this.colsThreshold == 0)
|
if (this.colsThreshold == 0)
|
||||||
this.colsThreshold = 1;
|
this.colsThreshold = 1;
|
||||||
|
|
||||||
this.blackbarThreshold = this.conf.blackLevel + this.settings.active.arDetect.blackbar.threshold;
|
this.blackbarThreshold = this.conf.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;
|
||||||
|
|
||||||
// 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
|
||||||
if(guardLineOut){
|
if(guardLineOut){
|
||||||
if(guardLineOut.imageFail && !guardLineOut.blackbarFail && this.conf.guardLine.blackbar.top) {
|
if(guardLineOut.imageFail && !guardLineOut.blackbarFail && this.conf.guardLine.blackbar.top) {
|
||||||
upper_top = this.conf.guardLine.blackbar.top;
|
upper_top = this.conf.guardLine.blackbar.top;
|
||||||
upper_bottom = this.conf.canvas.height >> 1;
|
upper_bottom = this.conf.glCanvas.height >> 1;
|
||||||
lower_top = upper_bottom;
|
lower_top = upper_bottom;
|
||||||
lower_bottom = this.conf.guardLine.blackbar.bottom;
|
lower_bottom = this.conf.guardLine.blackbar.bottom;
|
||||||
} else if (! guardLineOut.imageFail && !guardLineOut.blackbarFail && this.conf.guardLine.blackbar.top) {
|
} 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
|
// 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
|
// 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.
|
// 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
|
// 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.
|
// the point marked by guardLine.blackbar. Let's say 1/8 of canvas height on either side.
|
||||||
upper_top = 0;
|
upper_top = 0;
|
||||||
upper_bottom = this.conf.guardLine.blackbar.top + (this.conf.canvas.height >> 3);
|
upper_bottom = this.conf.guardLine.blackbar.top + (this.conf.glCanvas.height >> 3);
|
||||||
lower_top = this.conf.guardLine.blackbar.bottom - (this.conf.canvas.height >> 3);
|
lower_top = this.conf.guardLine.blackbar.bottom - (this.conf.glCanvas.height >> 3);
|
||||||
lower_bottom = this.conf.canvas.height - 1;
|
lower_bottom = this.conf.glCanvas.height - 1;
|
||||||
} else {
|
} else {
|
||||||
upper_top = 0;
|
upper_top = 0;
|
||||||
upper_bottom = (this.conf.canvas.height >> 1) /*- parseInt(this.conf.canvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
upper_bottom = (this.conf.glCanvas.height >> 1) /*- parseInt(this.conf.glCanvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
||||||
lower_top = (this.conf.canvas.height >> 1) /*+ parseInt(this.conf.canvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
lower_top = (this.conf.glCanvas.height >> 1) /*+ parseInt(this.conf.glCanvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
||||||
lower_bottom = this.conf.canvas.height - 1;
|
lower_bottom = this.conf.glCanvas.height - 1;
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
upper_top = 0;
|
upper_top = 0;
|
||||||
upper_bottom = (this.conf.canvas.height >> 1) /*- parseInt(this.conf.canvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
upper_bottom = (this.conf.glCanvas.height >> 1) /*- parseInt(this.conf.glCanvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
||||||
lower_top = (this.conf.canvas.height >> 1) /*+ parseInt(this.conf.canvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
lower_top = (this.conf.glCanvas.height >> 1) /*+ parseInt(this.conf.glCanvas.height * this.settings.active.arDetect.edgeDetection.middleIgnoredArea);*/
|
||||||
lower_bottom = this.conf.canvas.height - 1;
|
lower_bottom = this.conf.glCanvas.height - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.log('info', 'arDetect', '[EdgeDetect::findCandidates] searching for candidates on ranges', upper_top, '<->', upper_bottom, ';', lower_top, '<->', lower_bottom);
|
this.logger.log('info', 'arDetect', '[EdgeDetect::findCandidates] searching for candidates on ranges', upper_top, '<->', upper_bottom, ';', lower_top, '<->', lower_bottom);
|
||||||
|
|
||||||
let upper_top_corrected = upper_top * this.conf.canvasImageDataRowLength;
|
let upper_top_corrected = upper_top * this.conf.canvasImageDataRowLength;
|
||||||
let upper_bottom_corrected = upper_bottom * this.conf.canvasImageDataRowLength;
|
let upper_bottom_corrected = upper_bottom * this.conf.canvasImageDataRowLength;
|
||||||
let lower_top_corrected = lower_top * this.conf.canvasImageDataRowLength;
|
let lower_top_corrected = lower_top * this.conf.canvasImageDataRowLength;
|
||||||
let lower_bottom_corrected = lower_bottom * this.conf.canvasImageDataRowLength;
|
let 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, 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, true);
|
||||||
@ -140,9 +140,9 @@ class EdgeDetect{
|
|||||||
this._columnTest3_cross(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false);
|
this._columnTest3_cross(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false);
|
||||||
this._columnTest3_cross(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom, true);
|
this._columnTest3_cross(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom, true);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.logger.log('info', 'arDetect', '[EdgeDetect::findCandidates] candidates found -->', {res_top: res_top, res_bottom: res_bottom});
|
this.logger.log('info', 'arDetect', '[EdgeDetect::findCandidates] candidates found -->', {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) {
|
} catch (e) {
|
||||||
this.logger.log('error', 'debug', '[EdgeDetect::findCandidates] there was an error while finding candidates:', e);
|
this.logger.log('error', 'debug', '[EdgeDetect::findCandidates] there was an error while finding candidates:', e);
|
||||||
@ -157,7 +157,7 @@ class EdgeDetect{
|
|||||||
// NOTE: this is very simple and will need to be reworked in case we ever
|
// NOTE: this is very simple and will need to be reworked in case we ever
|
||||||
// go for quorum-based edge detection. (Probably not gonna happen)
|
// go for quorum-based edge detection. (Probably not gonna happen)
|
||||||
const topPoint = {
|
const topPoint = {
|
||||||
row: this.conf.canvas.height,
|
row: this.conf.glCanvas.height,
|
||||||
gradient: false, // does current row have a gradient sample
|
gradient: false, // does current row have a gradient sample
|
||||||
noGradient: false, // does current row have 100% confirmed edge sample
|
noGradient: false, // does current row have 100% confirmed edge sample
|
||||||
}
|
}
|
||||||
@ -211,7 +211,7 @@ class EdgeDetect{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (! topPoint.noGradient) {
|
if (! topPoint.noGradient) {
|
||||||
if (! bottomPoint.noGradient) {
|
if (! bottomPoint.noGradient) {
|
||||||
// top sample in both is a gradient with no solid sample present in that row
|
// top sample in both is a gradient with no solid sample present in that row
|
||||||
@ -220,7 +220,7 @@ class EdgeDetect{
|
|||||||
} else {
|
} else {
|
||||||
// if top gradient-only sample is closer to the edge than the bottom sample,
|
// if top gradient-only sample is closer to the edge than the bottom sample,
|
||||||
// validation also fails. Otherwise, we can assume success.
|
// validation also fails. Otherwise, we can assume success.
|
||||||
return (topPoint.row >= this.conf.canvas.height - bottomPoint.row);
|
return (topPoint.row >= this.conf.glCanvas.height - bottomPoint.row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ class EdgeDetect{
|
|||||||
// whether gradient-only result of bottom row is closer to the edge than than the top
|
// whether gradient-only result of bottom row is closer to the edge than than the top
|
||||||
// sample.
|
// sample.
|
||||||
if (! bottomPoint.noGradient) {
|
if (! bottomPoint.noGradient) {
|
||||||
return (topPoint.row < this.conf.canvas.height - bottomPoint.row);
|
return (topPoint.row < this.conf.glCanvas.height - bottomPoint.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -238,37 +238,37 @@ class EdgeDetect{
|
|||||||
edgeDetect(image, samples){
|
edgeDetect(image, samples){
|
||||||
let edgeCandidatesTop = {count: 0};
|
let edgeCandidatesTop = {count: 0};
|
||||||
let edgeCandidatesBottom = {count: 0};
|
let edgeCandidatesBottom = {count: 0};
|
||||||
|
|
||||||
let detections;
|
let detections;
|
||||||
let canvasWidth = this.conf.canvas.width;
|
let canvasWidth = this.conf.glCanvas.width;
|
||||||
let canvasHeight = this.conf.canvas.height;
|
let canvasHeight = this.conf.glCanvas.height;
|
||||||
|
|
||||||
let sampleStart, sampleEnd, loopEnd;
|
let sampleStart, sampleEnd, loopEnd;
|
||||||
let sampleRow_black, sampleRow_color;
|
let sampleRow_black, sampleRow_color;
|
||||||
|
|
||||||
let blackEdgeViolation = false;
|
let blackEdgeViolation = false;
|
||||||
|
|
||||||
let topEdgeCount = 0;
|
let topEdgeCount = 0;
|
||||||
let bottomEdgeCount = 0;
|
let bottomEdgeCount = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const sample of samples.res_top){
|
for (const sample of samples.res_top){
|
||||||
blackEdgeViolation = false; // reset this
|
blackEdgeViolation = false; // reset this
|
||||||
|
|
||||||
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is
|
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is
|
||||||
sampleStart = (sample.col << 2) - this.halfSample;
|
sampleStart = (sample.col << 2) - this.halfSample;
|
||||||
|
|
||||||
if(sampleStart < 0)
|
if(sampleStart < 0)
|
||||||
sampleStart = 0;
|
sampleStart = 0;
|
||||||
|
|
||||||
sampleEnd = sampleStart + this.sampleWidthBase;
|
sampleEnd = sampleStart + this.sampleWidthBase;
|
||||||
if (sampleEnd > this.conf.canvasImageDataRowLength)
|
if (sampleEnd > this.conf.canvasImageDataRowLength)
|
||||||
sampleEnd = this.conf.canvasImageDataRowLength;
|
sampleEnd = this.conf.canvasImageDataRowLength;
|
||||||
|
|
||||||
// calculate row offsets for imageData array
|
// calculate row offsets for imageData array
|
||||||
sampleRow_black = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx - 1) * this.conf.canvasImageDataRowLength;
|
sampleRow_black = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx - 1) * this.conf.canvasImageDataRowLength;
|
||||||
sampleRow_color = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength;
|
sampleRow_color = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength;
|
||||||
|
|
||||||
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
|
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
|
||||||
// even a single black edge violation means the candidate is not an edge
|
// even a single black edge violation means the candidate is not an edge
|
||||||
loopEnd = sampleRow_black + sampleEnd;
|
loopEnd = sampleRow_black + sampleEnd;
|
||||||
@ -284,7 +284,7 @@ class EdgeDetect{
|
|||||||
if (blackEdgeViolation) {
|
if (blackEdgeViolation) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
detections = 0;
|
detections = 0;
|
||||||
loopEnd = sampleRow_color + sampleEnd;
|
loopEnd = sampleRow_color + sampleEnd;
|
||||||
|
|
||||||
@ -294,40 +294,40 @@ class EdgeDetect{
|
|||||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop);
|
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const sample of samples.res_bottom){
|
for (const sample of samples.res_bottom){
|
||||||
blackEdgeViolation = false; // reset this
|
blackEdgeViolation = false; // reset this
|
||||||
|
|
||||||
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but this.halfSample is
|
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but this.halfSample is
|
||||||
sampleStart = (sample.col << 2) - this.halfSample;
|
sampleStart = (sample.col << 2) - this.halfSample;
|
||||||
|
|
||||||
if(sampleStart < 0)
|
if(sampleStart < 0)
|
||||||
sampleStart = 0;
|
sampleStart = 0;
|
||||||
|
|
||||||
sampleEnd = sampleStart + this.sampleWidthBase;
|
sampleEnd = sampleStart + this.sampleWidthBase;
|
||||||
if(sampleEnd > this.conf.canvasImageDataRowLength)
|
if(sampleEnd > this.conf.canvasImageDataRowLength)
|
||||||
sampleEnd = this.conf.canvasImageDataRowLength;
|
sampleEnd = this.conf.canvasImageDataRowLength;
|
||||||
|
|
||||||
// calculate row offsets for imageData array
|
// calculate row offsets for imageData array
|
||||||
sampleRow_black = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx + 1) * this.conf.canvasImageDataRowLength;
|
sampleRow_black = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx + 1) * this.conf.canvasImageDataRowLength;
|
||||||
sampleRow_color = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength;
|
sampleRow_color = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength;
|
||||||
|
|
||||||
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
|
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
|
||||||
// even a single black edge violation means the candidate is not an edge
|
// even a single black edge violation means the candidate is not an edge
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// če je bila črna črta skrunjena, preverimo naslednjega kandidata
|
// če je bila črna črta skrunjena, preverimo naslednjega kandidata
|
||||||
// if we failed, we continue our search with the next candidate
|
// if we failed, we continue our search with the next candidate
|
||||||
if (blackEdgeViolation) {
|
if (blackEdgeViolation) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
detections = 0;
|
detections = 0;
|
||||||
loopEnd = sampleRow_color + sampleEnd;
|
loopEnd = sampleRow_color + sampleEnd;
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ class EdgeDetect{
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.log('error', 'debug', '[EdgeDetect::edgeDetect] There was an error:', e);
|
this.logger.log('error', 'debug', '[EdgeDetect::edgeDetect] There was an error:', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
edgeCandidatesTop: edgeCandidatesTop,
|
edgeCandidatesTop: edgeCandidatesTop,
|
||||||
edgeCandidatesTopCount: edgeCandidatesTop.count,
|
edgeCandidatesTopCount: edgeCandidatesTop.count,
|
||||||
@ -352,13 +352,13 @@ class EdgeDetect{
|
|||||||
edgePostprocess(edges){
|
edgePostprocess(edges){
|
||||||
let edgesTop = [];
|
let edgesTop = [];
|
||||||
let edgesBottom = [];
|
let edgesBottom = [];
|
||||||
let alignMargin = this.conf.canvas.height * this.settings.active.arDetect.allowedMisaligned;
|
let alignMargin = this.conf.glCanvas.height * this.settings.active.arDetect.allowedMisaligned;
|
||||||
|
|
||||||
let missingEdge = edges.edgeCandidatesTopCount == 0 || edges.edgeCandidatesBottomCount == 0;
|
let missingEdge = edges.edgeCandidatesTopCount == 0 || edges.edgeCandidatesBottomCount == 0;
|
||||||
|
|
||||||
// pretvorimo objekt v tabelo
|
// pretvorimo objekt v tabelo
|
||||||
// convert objects to array
|
// convert objects to array
|
||||||
|
|
||||||
delete(edges.edgeCandidatesTop.count);
|
delete(edges.edgeCandidatesTop.count);
|
||||||
delete(edges.edgeCandidatesBottom.count);
|
delete(edges.edgeCandidatesBottom.count);
|
||||||
|
|
||||||
@ -372,40 +372,40 @@ class EdgeDetect{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( edges.edgeCandidatesBottomCount > 0){
|
if( edges.edgeCandidatesBottomCount > 0){
|
||||||
for(let e in edges.edgeCandidatesBottom){
|
for(let e in edges.edgeCandidatesBottom){
|
||||||
let edge = edges.edgeCandidatesBottom[e];
|
let edge = edges.edgeCandidatesBottom[e];
|
||||||
edgesBottom.push({
|
edgesBottom.push({
|
||||||
distance: this.conf.canvas.height - edge.offset,
|
distance: this.conf.glCanvas.height - edge.offset,
|
||||||
absolute: edge.offset,
|
absolute: edge.offset,
|
||||||
count: edge.count
|
count: edge.count
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort by distance
|
// sort by distance
|
||||||
edgesTop = edgesTop.sort((a,b) => {return a.distance - b.distance});
|
edgesTop = edgesTop.sort((a,b) => {return a.distance - b.distance});
|
||||||
edgesBottom = edgesBottom.sort((a,b) => {return a.distance - b.distance});
|
edgesBottom = edgesBottom.sort((a,b) => {return a.distance - b.distance});
|
||||||
|
|
||||||
|
|
||||||
// če za vsako stran (zgoraj in spodaj) poznamo vsaj enega kandidata, potem lahko preverimo nekaj
|
// če za vsako stran (zgoraj in spodaj) poznamo vsaj enega kandidata, potem lahko preverimo nekaj
|
||||||
// stvari
|
// stvari
|
||||||
|
|
||||||
if (!missingEdge){
|
if (!missingEdge){
|
||||||
// predvidevamo, da je logo zgoraj ali spodaj, nikakor pa ne na obeh straneh hkrati.
|
// predvidevamo, da je logo zgoraj ali spodaj, nikakor pa ne na obeh straneh hkrati.
|
||||||
// če kanal logotipa/watermarka ni vključil v video, potem si bosta razdaliji (edge.distance) prvih ključev
|
// če kanal logotipa/watermarka ni vključil v video, potem si bosta razdaliji (edge.distance) prvih ključev
|
||||||
// zgornjega in spodnjega roba približno enaki
|
// zgornjega in spodnjega roba približno enaki
|
||||||
//
|
//
|
||||||
// we'll assume that no youtube channel is rude enough to put channel logo/watermark both on top and the bottom
|
// we'll assume that no youtube channel is rude enough to put channel logo/watermark both on top and the bottom
|
||||||
// of the video. If logo's not included in the video, distances (edge.distance) of the first two keys should be
|
// of the video. If logo's not included in the video, distances (edge.distance) of the first two keys should be
|
||||||
// roughly equal. Let's check for that.
|
// roughly equal. Let's check for that.
|
||||||
if( edgesTop[0].distance >= edgesBottom[0].distance - alignMargin &&
|
if( edgesTop[0].distance >= edgesBottom[0].distance - alignMargin &&
|
||||||
edgesTop[0].distance <= edgesBottom[0].distance + alignMargin ){
|
edgesTop[0].distance <= edgesBottom[0].distance + alignMargin ){
|
||||||
|
|
||||||
let blackbarWidth = edgesTop[0].distance > edgesBottom[0].distance ?
|
let blackbarWidth = edgesTop[0].distance > edgesBottom[0].distance ?
|
||||||
edgesTop[0].distance : edgesBottom[0].distance;
|
edgesTop[0].distance : edgesBottom[0].distance;
|
||||||
|
|
||||||
if (edgesTop[0].count + edgesBottom[0].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold
|
if (edgesTop[0].count + edgesBottom[0].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold
|
||||||
|| ( edgesTop[0].count > this.settings.active.arDetect.edgeDetection.confirmationThreshold && edgesBottom[0].count > this.settings.active.arDetect.edgeDetection.confirmationThreshold) ){
|
|| ( edgesTop[0].count > this.settings.active.arDetect.edgeDetection.confirmationThreshold && edgesBottom[0].count > this.settings.active.arDetect.edgeDetection.confirmationThreshold) ){
|
||||||
return {
|
return {
|
||||||
@ -419,7 +419,7 @@ class EdgeDetect{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// torej, lahko da je na sliki watermark. Lahko, da je slika samo ornh črna. Najprej preverimo za watermark
|
// torej, lahko da je na sliki watermark. Lahko, da je slika samo ornh črna. Najprej preverimo za watermark
|
||||||
// it could be watermark. It could be a dark frame. Let's check for watermark first.
|
// it could be watermark. It could be a dark frame. Let's check for watermark first.
|
||||||
if (edgesTop[0].distance < edgesBottom[0].distance &&
|
if (edgesTop[0].distance < edgesBottom[0].distance &&
|
||||||
@ -428,16 +428,16 @@ class EdgeDetect{
|
|||||||
// možno, da je watermark zgoraj. Preverimo, če se kateri od drugih potencialnih robov na zgornjem robu
|
// možno, da je watermark zgoraj. Preverimo, če se kateri od drugih potencialnih robov na zgornjem robu
|
||||||
// ujema s prvim spodnjim (+/- variance). Če je temu tako, potem bo verjetno watermark. Logo mora imeti
|
// ujema s prvim spodnjim (+/- variance). Če je temu tako, potem bo verjetno watermark. Logo mora imeti
|
||||||
// manj vzorcev kot navaden rob.
|
// manj vzorcev kot navaden rob.
|
||||||
|
|
||||||
if (edgesTop[0].length > 1){
|
if (edgesTop[0].length > 1){
|
||||||
let lowMargin = edgesBottom[0].distance - alignMargin;
|
let lowMargin = edgesBottom[0].distance - alignMargin;
|
||||||
let highMargin = edgesBottom[0].distance + alignMargin;
|
let highMargin = edgesBottom[0].distance + alignMargin;
|
||||||
|
|
||||||
for (let i = 1; i < edgesTop.length; i++){
|
for (let i = 1; i < edgesTop.length; i++){
|
||||||
if(edgesTop[i].distance >= lowMargin && edgesTop[i].distance <= highMargin){
|
if(edgesTop[i].distance >= lowMargin && edgesTop[i].distance <= highMargin){
|
||||||
// dobili smo dejanski rob. vrnimo ga
|
// dobili smo dejanski rob. vrnimo ga
|
||||||
// we found the actual edge. let's return that.
|
// we found the actual edge. let's return that.
|
||||||
let blackbarWidth = edgesTop[i].distance > edgesBottom[0].distance ?
|
let blackbarWidth = edgesTop[i].distance > edgesBottom[0].distance ?
|
||||||
edgesTop[i].distance : edgesBottom[0].distance;
|
edgesTop[i].distance : edgesBottom[0].distance;
|
||||||
|
|
||||||
if (edgesTop[i].count + edgesBottom[0].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold
|
if (edgesTop[i].count + edgesBottom[0].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold
|
||||||
@ -447,7 +447,7 @@ class EdgeDetect{
|
|||||||
blackbarWidth: blackbarWidth,
|
blackbarWidth: blackbarWidth,
|
||||||
guardLineTop: edgesTop[i].distance,
|
guardLineTop: edgesTop[i].distance,
|
||||||
guardLineBottom: edgesBottom[0].absolute,
|
guardLineBottom: edgesBottom[0].absolute,
|
||||||
|
|
||||||
top: edgesTop[i].distance,
|
top: edgesTop[i].distance,
|
||||||
bottom: edgesBottom[0].distance
|
bottom: edgesBottom[0].distance
|
||||||
};
|
};
|
||||||
@ -459,18 +459,18 @@ class EdgeDetect{
|
|||||||
if (edgesBottom[0].distance < edgesTop[0].distance &&
|
if (edgesBottom[0].distance < edgesTop[0].distance &&
|
||||||
edgesBottom[0].count < edgesTop[0].count &&
|
edgesBottom[0].count < edgesTop[0].count &&
|
||||||
edgesBottom[0].count < this.conf.sampleCols.length * this.settings.active.arDetect.edgeDetection.logoThreshold){
|
edgesBottom[0].count < this.conf.sampleCols.length * this.settings.active.arDetect.edgeDetection.logoThreshold){
|
||||||
|
|
||||||
if(edgesBottom[0].length > 1){
|
if(edgesBottom[0].length > 1){
|
||||||
let lowMargin = edgesTop[0].distance - alignMargin;
|
let lowMargin = edgesTop[0].distance - alignMargin;
|
||||||
let highMargin = edgesTop[0].distance + alignMargin;
|
let highMargin = edgesTop[0].distance + alignMargin;
|
||||||
|
|
||||||
for(let i = 1; i < edgesBottom.length; i++){
|
for(let i = 1; i < edgesBottom.length; i++){
|
||||||
if (edgesBottom[i].distance >= lowMargin && edgesTop[i].distance <= highMargin) {
|
if (edgesBottom[i].distance >= lowMargin && edgesTop[i].distance <= highMargin) {
|
||||||
// dobili smo dejanski rob. vrnimo ga
|
// dobili smo dejanski rob. vrnimo ga
|
||||||
// we found the actual edge. let's return that.
|
// we found the actual edge. let's return that.
|
||||||
let blackbarWidth = edgesBottom[i].distance > edgesTop[0].distance ?
|
let blackbarWidth = edgesBottom[i].distance > edgesTop[0].distance ?
|
||||||
edgesBottom[i].distance : edgesTop[0].distance;
|
edgesBottom[i].distance : edgesTop[0].distance;
|
||||||
|
|
||||||
if (edgesTop[0].count + edgesBottom[i].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold
|
if (edgesTop[0].count + edgesBottom[i].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold
|
||||||
|| (edgesTop[0].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold && edgesBottom[i].count > this.settings.active.arDetect.edgeDetection.confirmationThreshold)) {
|
|| (edgesTop[0].count > this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold && edgesBottom[i].count > this.settings.active.arDetect.edgeDetection.confirmationThreshold)) {
|
||||||
return {
|
return {
|
||||||
@ -489,22 +489,22 @@ class EdgeDetect{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// zgornjega ali spodnjega roba nismo zaznali. Imamo še en trik, s katerim lahko poskusimo
|
// zgornjega ali spodnjega roba nismo zaznali. Imamo še en trik, s katerim lahko poskusimo
|
||||||
// določiti razmerje stranic
|
// določiti razmerje stranic
|
||||||
// either the top or the bottom edge remains undetected, but we have one more trick that we
|
// either the top or the bottom edge remains undetected, but we have one more trick that we
|
||||||
// can try. It also tries to work around logos.
|
// can try. It also tries to work around logos.
|
||||||
|
|
||||||
const edgeDetectionThreshold = this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold;
|
const edgeDetectionThreshold = this.settings.active.arDetect.edgeDetection.singleSideConfirmationThreshold;
|
||||||
|
|
||||||
if (edges.edgeCandidatesTopCount == 0 && edges.edgeCandidatesBottomCount != 0){
|
if (edges.edgeCandidatesTopCount == 0 && edges.edgeCandidatesBottomCount != 0){
|
||||||
for(let edge of edgesBottom){
|
for(let edge of edgesBottom){
|
||||||
if(edge.count >= edgeDetectionThreshold)
|
if(edge.count >= edgeDetectionThreshold)
|
||||||
return {
|
return {
|
||||||
status: EdgeStatus.ARKnown,
|
status: EdgeStatus.ARKnown,
|
||||||
blackbarWidth: edge.distance,
|
blackbarWidth: edge.distance,
|
||||||
guardLineTop: null,
|
guardLineTop: null,
|
||||||
guardLineBottom: edge.bottom,
|
guardLineBottom: edge.bottom,
|
||||||
|
|
||||||
top: edge.distance,
|
top: edge.distance,
|
||||||
bottom: edge.distance
|
bottom: edge.distance
|
||||||
}
|
}
|
||||||
@ -518,7 +518,7 @@ class EdgeDetect{
|
|||||||
blackbarWidth: edge.distance,
|
blackbarWidth: edge.distance,
|
||||||
guardLineTop: edge.top,
|
guardLineTop: edge.top,
|
||||||
guardLineBottom: null,
|
guardLineBottom: null,
|
||||||
|
|
||||||
top: edge.distance,
|
top: edge.distance,
|
||||||
bottom: edge.distance
|
bottom: edge.distance
|
||||||
}
|
}
|
||||||
@ -529,7 +529,7 @@ class EdgeDetect{
|
|||||||
// if we reach this bit, we have failed in determining aspect ratio. It remains unknown.
|
// if we reach this bit, we have failed in determining aspect ratio. It remains unknown.
|
||||||
return {status: EdgeStatus.ARUnknown}
|
return {status: EdgeStatus.ARUnknown}
|
||||||
}
|
}
|
||||||
|
|
||||||
pillarTest(image){
|
pillarTest(image){
|
||||||
// preverimo, če na sliki obstajajo navpične črne obrobe. Vrne 'true' če so zaznane (in če so približno enako debele), 'false' sicer.
|
// 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.
|
// true vrne tudi, če zaznamo preveč črnine.
|
||||||
@ -537,20 +537,20 @@ class EdgeDetect{
|
|||||||
// checks the image for presence of vertical pillars. Less accurate than 'find blackbar limits'. If we find a non-black object that's
|
// checks the image for presence of vertical pillars. Less accurate than 'find blackbar limits'. If we find a non-black object that's
|
||||||
// roughly centered, we return true. Otherwise we return false.
|
// roughly centered, we return true. Otherwise we return false.
|
||||||
// we also return true if we detect too much black
|
// we also return true if we detect too much black
|
||||||
|
|
||||||
let blackbarThreshold, upper, lower;
|
let blackbarThreshold, upper, lower;
|
||||||
blackbarThreshold = this.conf.blackLevel + this.settings.active.arDetect.blackbar.threshold;
|
blackbarThreshold = this.conf.blackLevel + this.settings.active.arDetect.blackbar.threshold;
|
||||||
|
|
||||||
|
|
||||||
let middleRowStart = (this.conf.canvas.height >> 1) * this.conf.canvas.width;
|
let middleRowStart = (this.conf.glCanvas.height >> 1) * this.conf.glCanvas.width;
|
||||||
let middleRowEnd = middleRowStart + this.conf.canvas.width - 1;
|
let middleRowEnd = middleRowStart + this.conf.glCanvas.width - 1;
|
||||||
|
|
||||||
let rowStart = middleRowStart << 2;
|
let rowStart = middleRowStart << 2;
|
||||||
let midpoint = (middleRowStart + (this.conf.canvas.width >> 1)) << 2
|
let midpoint = (middleRowStart + (this.conf.glCanvas.width >> 1)) << 2
|
||||||
let rowEnd = middleRowEnd << 2;
|
let rowEnd = middleRowEnd << 2;
|
||||||
|
|
||||||
let edge_left = -1, edge_right = -1;
|
let edge_left = -1, edge_right = -1;
|
||||||
|
|
||||||
// preverimo na levi strani
|
// preverimo na levi strani
|
||||||
// let's check for edge on the left side
|
// let's check for edge on the left side
|
||||||
for(let i = rowStart; i < midpoint; i+=4){
|
for(let i = rowStart; i < midpoint; i+=4){
|
||||||
@ -559,40 +559,40 @@ class EdgeDetect{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// preverimo na desni strani
|
// preverimo na desni strani
|
||||||
// check on the right
|
// check on the right
|
||||||
for(let i = rowEnd; i > midpoint; i-= 4){
|
for(let i = rowEnd; i > midpoint; i-= 4){
|
||||||
if(image[i] > blackbarThreshold || image[i+1] > blackbarThreshold || image[i+2] > blackbarThreshold){
|
if(image[i] > blackbarThreshold || image[i+1] > blackbarThreshold || image[i+2] > blackbarThreshold){
|
||||||
edge_right = this.conf.canvas.width - ((i - rowStart) >> 2);
|
edge_right = this.conf.glCanvas.width - ((i - rowStart) >> 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// če je katerikoli -1, potem imamo preveč črnine
|
// če je katerikoli -1, potem imamo preveč črnine
|
||||||
// we probably have too much black if either of those two is -1
|
// we probably have too much black if either of those two is -1
|
||||||
if(edge_left == -1 || edge_right == -1){
|
if(edge_left == -1 || edge_right == -1){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// če sta oba robova v mejah merske napake, potem vrnemo 'false'
|
// če sta oba robova v mejah merske napake, potem vrnemo 'false'
|
||||||
// if both edges resemble rounding error, we retunr 'false'
|
// if both edges resemble rounding error, we retunr 'false'
|
||||||
if(edge_left < this.settings.active.arDetect.pillarTest.ignoreThinPillarsPx && edge_right < this.settings.active.arDetect.pillarTest.ignoreThinPillarsPx){
|
if(edge_left < this.settings.active.arDetect.pillarTest.ignoreThinPillarsPx && edge_right < this.settings.active.arDetect.pillarTest.ignoreThinPillarsPx){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let edgeError = this.settings.active.arDetect.pillarTest.allowMisaligned;
|
let edgeError = this.settings.active.arDetect.pillarTest.allowMisaligned;
|
||||||
let error_low = 1 - edgeError;
|
let error_low = 1 - edgeError;
|
||||||
let error_hi = 1 + edgeError;
|
let error_hi = 1 + edgeError;
|
||||||
|
|
||||||
// če sta 'edge_left' in 'edge_right' podobna/v mejah merske napake, potem vrnemo true — lahko da smo našli logo na sredini zaslona
|
// če sta 'edge_left' in 'edge_right' podobna/v mejah merske napake, potem vrnemo true — lahko da smo našli logo na sredini zaslona
|
||||||
// if 'edge_left' and 'edge_right' are similar enough to each other, we return true. If we found a logo in a black frame, we could
|
// if 'edge_left' and 'edge_right' are similar enough to each other, we return true. If we found a logo in a black frame, we could
|
||||||
// crop too eagerly
|
// crop too eagerly
|
||||||
if( (edge_left * error_low) < edge_right &&
|
if( (edge_left * error_low) < edge_right &&
|
||||||
(edge_left * error_hi) > edge_right ){
|
(edge_left * error_hi) > edge_right ){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// če se ne zgodi nič od neštetega, potem nismo našli problemov
|
// če se ne zgodi nič od neštetega, potem nismo našli problemov
|
||||||
// if none of the above, we haven't found a problem
|
// if none of the above, we haven't found a problem
|
||||||
return false;
|
return false;
|
||||||
@ -607,8 +607,8 @@ class EdgeDetect{
|
|||||||
// Here's a fun thing. I reckon this bit of code could potentially run often enough that L1/L2 cache misses
|
// Here's a fun thing. I reckon this bit of code could potentially run often enough that L1/L2 cache misses
|
||||||
// could really start to add up (especially if I figure the RAM usage problem which causes insane RAM usage
|
// could really start to add up (especially if I figure the RAM usage problem which causes insane RAM usage
|
||||||
// if you run this 30-60 times a second)
|
// if you run this 30-60 times a second)
|
||||||
//
|
//
|
||||||
// so here's two functions. _columnTest3_cross has some optimization that tries to minimize cache misses,
|
// so here's two functions. _columnTest3_cross has some optimization that tries to minimize cache misses,
|
||||||
// but the problem is that I don't actually know 100% what I'm doing so it might be pointless. It scans the
|
// but the problem is that I don't actually know 100% what I'm doing so it might be pointless. It scans the
|
||||||
// image array line-by-line, rather than column-by-column. This has some advantages (e.g. we can end the
|
// image array line-by-line, rather than column-by-column. This has some advantages (e.g. we can end the
|
||||||
// search for letterbox early), and some disadvantages (the code is a mess)
|
// search for letterbox early), and some disadvantages (the code is a mess)
|
||||||
@ -624,13 +624,13 @@ class EdgeDetect{
|
|||||||
let tmpVal = 0;
|
let tmpVal = 0;
|
||||||
let increment, arrayStart, arrayEnd;
|
let increment, arrayStart, arrayEnd;
|
||||||
|
|
||||||
let loopCond, loopComparator, loopIndex;
|
let loopCond, loopComparator, loopIndex;
|
||||||
|
|
||||||
if (reverseSearchDirection) {
|
if (reverseSearchDirection) {
|
||||||
increment = -this.conf.canvasImageDataRowLength;
|
increment = -this.conf.canvasImageDataRowLength;
|
||||||
// don't subtract this.conf.canvasImageDataRowLength — it has already been accounted for
|
// don't subtract this.conf.canvasImageDataRowLength — it has already been accounted for
|
||||||
// when we calculated bottom and top
|
// when we calculated bottom and top
|
||||||
arrayStart = bottom;
|
arrayStart = bottom;
|
||||||
arrayEnd = top;
|
arrayEnd = top;
|
||||||
|
|
||||||
// this is a hack so we get pointer-like things rather than values
|
// this is a hack so we get pointer-like things rather than values
|
||||||
@ -669,7 +669,7 @@ class EdgeDetect{
|
|||||||
// loopIndex.i could actually be loopCond.compare.i (comparator) and
|
// loopIndex.i could actually be loopCond.compare.i (comparator) and
|
||||||
// loopComparator.i could actually be loopCond.index.i (real index)
|
// loopComparator.i could actually be loopCond.index.i (real index)
|
||||||
for (loopCond.index.i = arrayStart; loopIndex.i < loopComparator.i; loopCond.index.i += increment) {
|
for (loopCond.index.i = arrayStart; loopIndex.i < loopComparator.i; loopCond.index.i += increment) {
|
||||||
|
|
||||||
// če smo našli toliko mejnih točk, da s preostalimi stolpci ne moremo doseči naše meje, potem prenehamo
|
// če smo našli toliko mejnih točk, da s preostalimi stolpci ne moremo doseči naše meje, potem prenehamo
|
||||||
// if we found enough edge points so that we couldn't top that limit with remaining columns, then we stop
|
// if we found enough edge points so that we couldn't top that limit with remaining columns, then we stop
|
||||||
// searching forward
|
// searching forward
|
||||||
@ -677,7 +677,7 @@ class EdgeDetect{
|
|||||||
if (edgeDetectColsLeft < this.colsThreshold || edgeDetectCount >= this.colsThreshold) {
|
if (edgeDetectColsLeft < this.colsThreshold || edgeDetectCount >= this.colsThreshold) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
edgeDetectCount = 0;
|
edgeDetectCount = 0;
|
||||||
|
|
||||||
|
|
||||||
// če v eni vrstici dobimo dovolj točk, ki grejo čez našo mejo zaznavanja, potem bomo nehali
|
// če v eni vrstici dobimo dovolj točk, ki grejo čez našo mejo zaznavanja, potem bomo nehali
|
||||||
@ -694,13 +694,13 @@ class EdgeDetect{
|
|||||||
// najprej preverimo, če je piksel presegel mejo črnega robu
|
// najprej preverimo, če je piksel presegel mejo črnega robu
|
||||||
// first we check whether blackbarThreshold was exceeded
|
// first we check whether blackbarThreshold was exceeded
|
||||||
if (! colsTmp[c].blackFound) {
|
if (! colsTmp[c].blackFound) {
|
||||||
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 ){
|
||||||
|
|
||||||
colsTmp[c].col = colsIn[c].value;
|
colsTmp[c].col = colsIn[c].value;
|
||||||
colsTmp[c].blackFound = true;
|
colsTmp[c].blackFound = true;
|
||||||
colsTmp[c].blackRow = ~~(loopCond.index.i / this.conf.canvasImageDataRowLength);
|
colsTmp[c].blackRow = ~~(loopCond.index.i / this.conf.canvasImageDataRowLength);
|
||||||
|
|
||||||
// prisili, da se zanka izvede še enkrat ter preveri,
|
// prisili, da se zanka izvede še enkrat ter preveri,
|
||||||
// ali trenuten piksel preseže tudi imageThreshold
|
// ali trenuten piksel preseže tudi imageThreshold
|
||||||
@ -719,13 +719,13 @@ class EdgeDetect{
|
|||||||
// when we get a pixel over imageTreshold or gradientSampleSize, we flip the imageFound. We'll bother
|
// when we get a pixel over imageTreshold or gradientSampleSize, we flip the imageFound. We'll bother
|
||||||
// with whether that's legit in analysis step, which will follow soon (tm)
|
// with whether that's legit in analysis step, which will follow soon (tm)
|
||||||
|
|
||||||
if (image[tmpI] > this.imageThreshold ||
|
if (image[tmpI] > this.imageThreshold ||
|
||||||
image[tmpI + 1] > this.imageThreshold ||
|
image[tmpI + 1] > this.imageThreshold ||
|
||||||
image[tmpI + 2] > this.imageThreshold ){
|
image[tmpI + 2] > this.imageThreshold ){
|
||||||
|
|
||||||
colsTmp[c].imageRow = ~~(loopCond.index.i / this.conf.canvasImageDataRowLength)
|
colsTmp[c].imageRow = ~~(loopCond.index.i / this.conf.canvasImageDataRowLength)
|
||||||
|
|
||||||
|
|
||||||
colsTmp[c].imageFound = true;
|
colsTmp[c].imageFound = true;
|
||||||
edgeDetectCount++;
|
edgeDetectCount++;
|
||||||
}
|
}
|
||||||
@ -743,7 +743,7 @@ class EdgeDetect{
|
|||||||
colsTmp[c].imageFound = true;
|
colsTmp[c].imageFound = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -770,7 +770,7 @@ class EdgeDetect{
|
|||||||
// if we detected gradient, we'll analyse whether gradient is legit
|
// if we detected gradient, we'll analyse whether gradient is legit
|
||||||
for (i = 0; i < c.diffIndex; i++) {
|
for (i = 0; i < c.diffIndex; i++) {
|
||||||
tmpVal += c.diffs[i];
|
tmpVal += c.diffs[i];
|
||||||
|
|
||||||
// if difference is negative, we aren't looking at a gradient
|
// if difference is negative, we aren't looking at a gradient
|
||||||
if (c.diffs[i] < this.settings.active.arDetect.blackbar.gradientNegativeTreshold) {
|
if (c.diffs[i] < this.settings.active.arDetect.blackbar.gradientNegativeTreshold) {
|
||||||
colsOut.push({
|
colsOut.push({
|
||||||
@ -789,7 +789,7 @@ class EdgeDetect{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case neither of the previous options happens, we might have a gradient.
|
// in case neither of the previous options happens, we might have a gradient.
|
||||||
// Since this column is sus af, we don't include it for further examination/
|
// Since this column is sus af, we don't include it for further examination/
|
||||||
// determining aspect ratio
|
// determining aspect ratio
|
||||||
}
|
}
|
||||||
@ -811,7 +811,7 @@ class EdgeDetect{
|
|||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// this means we're on a gradient. We still push an object to colsOut — this is
|
// this means we're on a gradient. We still push an object to colsOut — this is
|
||||||
// important. While "bad" detection doesn't help us with determining the aspect
|
// important. While "bad" detection doesn't help us with determining the aspect
|
||||||
// ratio, bad detections can prevent us from setting aspect ratio incorrectly.
|
// ratio, bad detections can prevent us from setting aspect ratio incorrectly.
|
||||||
// for example, if we detect a gradient closer to the frame edge than a proper
|
// for example, if we detect a gradient closer to the frame edge than a proper
|
||||||
@ -827,7 +827,7 @@ class EdgeDetect{
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// in this case, we aren't looking at a gradient. We also aren't looking at a
|
// in this case, we aren't looking at a gradient. We also aren't looking at a
|
||||||
// valid column
|
// valid column
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -877,18 +877,18 @@ class EdgeDetect{
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tmpI = i + (colsIn[c].value << 2);
|
tmpI = i + (colsIn[c].value << 2);
|
||||||
|
|
||||||
// najprej preverimo, če je piksel presegel mejo črnega robu
|
// najprej preverimo, če je piksel presegel mejo črnega robu
|
||||||
// first we check whether blackbarThreshold was exceeded
|
// first we check whether blackbarThreshold was exceeded
|
||||||
if(! colsIn[c].blackFound) {
|
if(! colsIn[c].blackFound) {
|
||||||
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[c].black = (i / this.conf.canvasImageDataRowLength) - 1;
|
colsOut[c].black = (i / this.conf.canvasImageDataRowLength) - 1;
|
||||||
colsOut[c].col = colsIn[c].value;
|
colsOut[c].col = colsIn[c].value;
|
||||||
colsIn[c].blackFound = 1;
|
colsIn[c].blackFound = 1;
|
||||||
|
|
||||||
// prisili, da se zanka izvede še enkrat ter preveri,
|
// prisili, da se zanka izvede še enkrat ter preveri,
|
||||||
// ali trenuten piksel preseže tudi imageThreshold
|
// ali trenuten piksel preseže tudi imageThreshold
|
||||||
//
|
//
|
||||||
@ -902,15 +902,15 @@ class EdgeDetect{
|
|||||||
colsIn[c].imageFound = true;
|
colsIn[c].imageFound = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da
|
// zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da
|
||||||
// predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli
|
// predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli
|
||||||
// blackThreshold
|
// blackThreshold
|
||||||
//
|
//
|
||||||
// then we check whether pixel exceeded imageThreshold
|
// then we check whether pixel exceeded imageThreshold
|
||||||
if (image[tmpI] > this.imageThreshold ||
|
if (image[tmpI] > this.imageThreshold ||
|
||||||
image[tmpI + 1] > this.imageThreshold ||
|
image[tmpI + 1] > this.imageThreshold ||
|
||||||
image[tmpI + 2] > this.imageThreshold ){
|
image[tmpI + 2] > this.imageThreshold ){
|
||||||
|
|
||||||
colsOut[c].image = (i / this.conf.canvasImageDataRowLength)
|
colsOut[c].image = (i / this.conf.canvasImageDataRowLength)
|
||||||
colsIn[c].imageFound = true;
|
colsIn[c].imageFound = true;
|
||||||
edgeDetectCount++;
|
edgeDetectCount++;
|
||||||
@ -943,7 +943,7 @@ class EdgeDetect{
|
|||||||
sum_avg += colsOut[c].diffs[i-1] - colsOut[c].diffs[i];
|
sum_avg += colsOut[c].diffs[i-1] - colsOut[c].diffs[i];
|
||||||
}
|
}
|
||||||
sum_avg /= colsOut[c].diffs.length - 2;
|
sum_avg /= colsOut[c].diffs.length - 2;
|
||||||
|
|
||||||
for (let i = 2; i <= colsOut[c].diffs; i++) {
|
for (let i = 2; i <= colsOut[c].diffs; i++) {
|
||||||
sum_avg += colsOut[c].diffs[i-1] - colsOut[c].diffs[i];
|
sum_avg += colsOut[c].diffs[i-1] - colsOut[c].diffs[i];
|
||||||
}
|
}
|
||||||
@ -952,18 +952,18 @@ class EdgeDetect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpI = i + (colsIn[c].value << 2);
|
tmpI = i + (colsIn[c].value << 2);
|
||||||
|
|
||||||
// najprej preverimo, če je piksel presegel mejo črnega robu
|
// najprej preverimo, če je piksel presegel mejo črnega robu
|
||||||
// first we check whether blackbarThreshold was exceeded
|
// first we check whether blackbarThreshold was exceeded
|
||||||
if(! colsIn[c].blackFound) {
|
if(! colsIn[c].blackFound) {
|
||||||
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[c].black = (i / this.conf.canvasImageDataRowLength) - 1;
|
colsOut[c].black = (i / this.conf.canvasImageDataRowLength) - 1;
|
||||||
colsOut[c].col = colsIn[c].value;
|
colsOut[c].col = colsIn[c].value;
|
||||||
colsIn[c].blackFound = 1;
|
colsIn[c].blackFound = 1;
|
||||||
|
|
||||||
// prisili, da se zanka izvede še enkrat ter preveri,
|
// prisili, da se zanka izvede še enkrat ter preveri,
|
||||||
// ali trenuten piksel preseže tudi imageThreshold
|
// ali trenuten piksel preseže tudi imageThreshold
|
||||||
//
|
//
|
||||||
@ -980,18 +980,18 @@ class EdgeDetect{
|
|||||||
colsIn[c].imageFound = true;
|
colsIn[c].imageFound = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da
|
// zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da
|
||||||
// predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli
|
// predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli
|
||||||
// blackThreshold
|
// blackThreshold
|
||||||
//
|
//
|
||||||
// then we check whether pixel exceeded imageThreshold
|
// then we check whether pixel exceeded imageThreshold
|
||||||
if (image[tmpI] > this.imageThreshold ||
|
if (image[tmpI] > this.imageThreshold ||
|
||||||
image[tmpI + 1] > this.imageThreshold ||
|
image[tmpI + 1] > this.imageThreshold ||
|
||||||
image[tmpI + 2] > this.imageThreshold ){
|
image[tmpI + 2] > this.imageThreshold ){
|
||||||
|
|
||||||
colsOut[c].image = (i / this.conf.canvasImageDataRowLength)
|
colsOut[c].image = (i / this.conf.canvasImageDataRowLength)
|
||||||
|
|
||||||
|
|
||||||
colsIn[c].imageFound = true;
|
colsIn[c].imageFound = true;
|
||||||
edgeDetectCount++;
|
edgeDetectCount++;
|
||||||
}
|
}
|
||||||
@ -1022,10 +1022,10 @@ class EdgeDetect{
|
|||||||
// najprej preverimo, če je piksel presegel mejo črnega robu
|
// najprej preverimo, če je piksel presegel mejo črnega robu
|
||||||
// first we check whether blackbarThreshold was exceeded
|
// first we check whether blackbarThreshold was exceeded
|
||||||
if(! colsIn[c].blackFound) {
|
if(! colsIn[c].blackFound) {
|
||||||
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[c].black = (i / this.conf.canvasImageDataRowLength);
|
colsOut[c].black = (i / this.conf.canvasImageDataRowLength);
|
||||||
colsOut[c].col = colsIn[c].value;
|
colsOut[c].col = colsIn[c].value;
|
||||||
colsIn[c].blackFound = true;
|
colsIn[c].blackFound = true;
|
||||||
@ -1043,15 +1043,15 @@ class EdgeDetect{
|
|||||||
colsIn[c].imageFound = true;
|
colsIn[c].imageFound = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da
|
// zatem preverimo, če je piksel presegel mejo, po kateri sklepamo, da
|
||||||
// predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli
|
// predstavlja sliko. Preverimo samo, če smo v stolpcu že presegli
|
||||||
// blackThreshold
|
// blackThreshold
|
||||||
//
|
//
|
||||||
// then we check whether pixel exceeded imageThreshold
|
// then we check whether pixel exceeded imageThreshold
|
||||||
if (image[tmpI] > this.imageThreshold ||
|
if (image[tmpI] > this.imageThreshold ||
|
||||||
image[tmpI + 1] > this.imageThreshold ||
|
image[tmpI + 1] > this.imageThreshold ||
|
||||||
image[tmpI + 2] > this.imageThreshold ){
|
image[tmpI + 2] > this.imageThreshold ){
|
||||||
|
|
||||||
colsOut[c].image = (i / this.conf.canvasImageDataRowLength)
|
colsOut[c].image = (i / this.conf.canvasImageDataRowLength)
|
||||||
colsIn[c].imageFound = true;
|
colsIn[c].imageFound = true;
|
||||||
edgeDetectCount++;
|
edgeDetectCount++;
|
||||||
@ -1072,11 +1072,11 @@ class EdgeDetect{
|
|||||||
for(let i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){
|
for(let i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){
|
||||||
for(const col of colsIn){
|
for(const 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 ){
|
||||||
|
|
||||||
const bottom = (i / this.conf.canvasImageDataRowLength) + 1;
|
const bottom = (i / this.conf.canvasImageDataRowLength) + 1;
|
||||||
colsOut.push({
|
colsOut.push({
|
||||||
col: col,
|
col: col,
|
||||||
@ -1092,11 +1092,11 @@ class EdgeDetect{
|
|||||||
for(let i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){
|
for(let i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){
|
||||||
for(const col of colsIn){
|
for(const 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
|
||||||
@ -1116,11 +1116,11 @@ class EdgeDetect{
|
|||||||
// for(let i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){
|
// for(let i = bottom - this.conf.canvasImageDataRowLength; i >= top; i-= this.conf.canvasImageDataRowLength){
|
||||||
// for(let col of colsIn){
|
// for(let 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 ){
|
||||||
|
|
||||||
// let bottom = (i / this.conf.canvasImageDataRowLength) + 1;
|
// let bottom = (i / this.conf.canvasImageDataRowLength) + 1;
|
||||||
// colsOut.push({
|
// colsOut.push({
|
||||||
// col: col,
|
// col: col,
|
||||||
@ -1140,17 +1140,17 @@ class EdgeDetect{
|
|||||||
// for(let i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){
|
// for(let i = top; i < bottom; i+= this.conf.canvasImageDataRowLength){
|
||||||
// for(let col of colsIn){
|
// for(let 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);
|
||||||
// }
|
// }
|
||||||
@ -1183,7 +1183,7 @@ class EdgeDetect{
|
|||||||
// 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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user