Autodetection sorta functional again
This commit is contained in:
parent
eaa1a0975a
commit
d647046aee
@ -9,7 +9,7 @@ var Debug = {
|
||||
// debug: false,
|
||||
keyboard: true,
|
||||
debugResizer: true,
|
||||
// debugArDetect: true,
|
||||
debugArDetect: true,
|
||||
// debugStorage: false,
|
||||
// debugStorage: true,
|
||||
// comms: false,
|
||||
|
@ -54,17 +54,21 @@ var ExtensionConf = {
|
||||
blackbar: {
|
||||
blackLevel: 10, // everything darker than 10/255 across all RGB components is considered black by
|
||||
// default. blackLevel can decrease if we detect darker black.
|
||||
threshold: 16, // if pixel is darker than the sum of black level and this value, we count it as black
|
||||
threshold: 16, // if pixel is darker than the sum of black level and this value, we count it as black
|
||||
// on 0-255. Needs to be fairly high (8 might not cut it) due to compression
|
||||
// artifacts in the video itself
|
||||
imageThreshold: 4, // in order to detect pixel as "not black", the pixel must be brighter than
|
||||
imageThreshold: 16, // in order to detect pixel as "not black", the pixel must be brighter than
|
||||
// the sum of black level, threshold and this value.
|
||||
gradientThreshold: 2, // When trying to determine thickness of the black bars, we take 2 values: position of
|
||||
gradientThreshold: 2, // When trying to determine thickness of the black bars, we take 2 values: position of
|
||||
// the last pixel that's darker than our threshold, and position of the first pixel that's
|
||||
// brighter than our image threshold. If positions are more than this many pixels apart,
|
||||
// we assume we aren't looking at letterbox and thus don't correct the aspect ratio.
|
||||
gradientSampleSize: 8, // How far do we look to find the gradient
|
||||
antiGradientMode: AntiGradientMode.Strict,
|
||||
gradientSampleSize: 16, // How far do we look to find the gradient
|
||||
maxGradient: 6, // if two neighbouring pixels in gradientSampleSize differ by more than this, then we aren't
|
||||
// looking at a gradient
|
||||
gradientNegativeTreshold: -2,
|
||||
gradientMaxSD: 6, // reserved for future use
|
||||
antiGradientMode: AntiGradientMode.Lax,
|
||||
},
|
||||
variableBlackbarThresholdOptions: { // In case of poor bitrate videos, jpeg artifacts may cause us issues
|
||||
// FOR FUTURE USE
|
||||
|
@ -28,7 +28,7 @@ class EdgeDetect{
|
||||
}
|
||||
|
||||
findBars(image, sampleCols, direction = EdgeDetectPrimaryDirection.VERTICAL, quality = EdgeDetectQuality.IMPROVED, guardLineOut, blackFrameAnalysis){
|
||||
var fastCandidates, edgeCandidates, bars;
|
||||
let fastCandidates, edgeCandidates, bars;
|
||||
if (direction == EdgeDetectPrimaryDirection.VERTICAL) {
|
||||
fastCandidates = this.findCandidates(image, sampleCols, guardLineOut);
|
||||
|
||||
@ -36,7 +36,9 @@ class EdgeDetect{
|
||||
// edges = fastCandidates; // todo: processing
|
||||
// } else {
|
||||
edgeCandidates = this.edgeDetect(image, fastCandidates);
|
||||
console.log("edge candidates:", edgeCandidates)
|
||||
bars = this.edgePostprocess(edgeCandidates, this.conf.canvas.height);
|
||||
console.log("bars:", bars)
|
||||
|
||||
// }
|
||||
} else {
|
||||
@ -52,22 +54,19 @@ class EdgeDetect{
|
||||
|
||||
// const cols_a = sampleCols.slice(0);
|
||||
const cols_a = new Array(sampleCols.length);
|
||||
const res_top_preliminary = new Array(sampleCols.length);
|
||||
const res_top = [];
|
||||
|
||||
for (let i = 0; i < cols_a.length; i++) {
|
||||
cols_a[i] = {
|
||||
id: i,
|
||||
value: sampleCols[i],
|
||||
blackFound: false,
|
||||
imageFound: false,
|
||||
};
|
||||
res_top_preliminary[i] = {col: undefined, image: undefined, black: undefined};
|
||||
}
|
||||
|
||||
const cols_b = cols_a.slice(0);
|
||||
const res_bottom_preliminary = res_top_preliminary.slice(0);
|
||||
const res_bottom = [];
|
||||
|
||||
console.log("[EdgeDetect::findCandidates] cols a, b:", cols_a, cols_b);
|
||||
// console.log("[EdgeDetect::findCandidates] cols a, b (initial):", cols_a, cols_b);
|
||||
|
||||
|
||||
this.colsThreshold = sampleCols.length * this.settings.active.arDetect.edgeDetection.minColsForSearch;
|
||||
@ -118,62 +117,18 @@ class EdgeDetect{
|
||||
var lower_bottom_corrected = lower_bottom * this.conf.canvasImageDataRowLength;
|
||||
|
||||
// if(Debug.debugCanvas.enabled){
|
||||
// this._columnTest_dbgc(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top_preliminary, false);
|
||||
// this._columnTest_dbgc(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true);
|
||||
// this._columnTest_dbgc(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top, false);
|
||||
// this._columnTest_dbgc(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom, true);
|
||||
// } else {
|
||||
// this._columnTest(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top_preliminary, false);
|
||||
// this._columnTest(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true);
|
||||
this._columnTest2(image, upper_top_corrected, upper_bottom_corrected, cols_a, res_top_preliminary, false);
|
||||
this._columnTest2(image, lower_top_corrected, lower_bottom_corrected, cols_b, res_bottom_preliminary, true);
|
||||
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);
|
||||
// }
|
||||
|
||||
if(Debug.debug && Debug.debugArDetect){
|
||||
console.log("[EdgeDetect::findCandidates] candidates found -->", {res_top: res_top_preliminary, res_bottom: res_bottom_preliminary});
|
||||
if (Debug.debug && Debug.debugArDetect){
|
||||
console.log("[EdgeDetect::findCandidates] candidates found -->", {res_top: res_top, res_bottom: res_bottom});
|
||||
}
|
||||
|
||||
// preglejmo, kateri kandidati so neprimerni. (Neprimerni so tisti, pri katerih se
|
||||
// 'black' in 'image' razlikujeta za več kot settings.arDetect.blackbar.gradientThreshold)
|
||||
//
|
||||
// let's check which candidates are suitable. Suitable candidates have 'black' and 'image'
|
||||
// components differ by less than settings.arDetect.blackbar.gradientThreshold
|
||||
|
||||
const res_top = [];
|
||||
const res_bottom = [];
|
||||
|
||||
for (let item of res_top_preliminary) {
|
||||
if (this.settings.active.arDetect.blackbar.antiGradientMode === AntiGradientMode.Disabled) {
|
||||
res_top.push({top: item.image, col: item.col});
|
||||
} else if (this.settings.active.arDetect.blackbar.antiGradientMode === AntiGradientMode.Lax) {
|
||||
if (item.image === undefined || item.image <= item.black + this.settings.active.arDetect.blackbar.gradientThreshold) {
|
||||
res_top.push({top: item.image, col: item.col});
|
||||
}
|
||||
} else {
|
||||
if ( item.image !== undefined && item.image <= item.black + this.settings.active.arDetect.blackbar.gradientThreshold) {
|
||||
res_top.push({top: item.image, col: item.col});
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let item of res_bottom_preliminary) {
|
||||
if (!item.image) {
|
||||
continue;
|
||||
}
|
||||
if (this.settings.active.arDetect.blackbar.antiGradientMode === AntiGradientMode.Disabled) {
|
||||
res_bottom.push({bottom: item.image, col: item.col});
|
||||
} else {
|
||||
if ( (item.image !== undefined || this.settings.active.arDetect.blackbar.antiGradientMode === AntiGradientMode.Lax)
|
||||
&& item.image >= item.black - this.settings.active.arDetect.blackbar.gradientThreshold) {
|
||||
res_bottom.push({bottom: item.image, col: item.col});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// const res_top = res_top_preliminary;
|
||||
// const res_bottom = res_bottom_preliminary;
|
||||
|
||||
if(Debug.debug && Debug.debugArDetect){
|
||||
console.log("[EdgeDetect::findCandidates] candidates after processing -->", {res_top: res_top, res_bottom: res_bottom});
|
||||
}
|
||||
|
||||
|
||||
return {res_top: res_top, res_bottom: res_bottom};
|
||||
|
||||
} catch (e) {
|
||||
@ -200,10 +155,9 @@ class EdgeDetect{
|
||||
|
||||
var topEdgeCount = 0;
|
||||
var bottomEdgeCount = 0;
|
||||
|
||||
var sample;
|
||||
|
||||
for(sample of samples.res_top){
|
||||
|
||||
try {
|
||||
for (const sample of samples.res_top){
|
||||
blackEdgeViolation = false; // reset this
|
||||
|
||||
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is
|
||||
@ -217,8 +171,8 @@ class EdgeDetect{
|
||||
sampleEnd = this.conf.canvasImageDataRowLength;
|
||||
|
||||
// calculate row offsets for imageData array
|
||||
sampleRow_black = (sample.top - this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength;
|
||||
sampleRow_color = (sample.top + 1 + this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * 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;
|
||||
|
||||
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
|
||||
// even a single black edge violation means the candidate is not an edge
|
||||
@ -232,20 +186,21 @@ class EdgeDetect{
|
||||
|
||||
// če je bila črna črta skrunjena, preverimo naslednjega kandidata
|
||||
// if we failed, we continue our search with the next candidate
|
||||
if(blackEdgeViolation)
|
||||
if (blackEdgeViolation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
detections = 0;
|
||||
loopEnd = sampleRow_color + sampleEnd;
|
||||
|
||||
if(Debug.debugCanvas.enabled) {
|
||||
this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.top, edgeCandidatesTop)
|
||||
this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop)
|
||||
} else {
|
||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.top, edgeCandidatesTop)
|
||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop);
|
||||
}
|
||||
}
|
||||
|
||||
for(sample of samples.res_bottom){
|
||||
for (const sample of samples.res_bottom){
|
||||
blackEdgeViolation = false; // reset this
|
||||
|
||||
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but this.halfSample is
|
||||
@ -259,8 +214,8 @@ class EdgeDetect{
|
||||
sampleEnd = this.conf.canvasImageDataRowLength;
|
||||
|
||||
// calculate row offsets for imageData array
|
||||
sampleRow_black = (sample.bottom + this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength;
|
||||
sampleRow_color = (sample.bottom - 1 - this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * 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;
|
||||
|
||||
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
|
||||
// even a single black edge violation means the candidate is not an edge
|
||||
@ -274,18 +229,29 @@ class EdgeDetect{
|
||||
|
||||
// če je bila črna črta skrunjena, preverimo naslednjega kandidata
|
||||
// if we failed, we continue our search with the next candidate
|
||||
if(blackEdgeViolation)
|
||||
if (blackEdgeViolation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
detections = 0;
|
||||
loopEnd = sampleRow_color + sampleEnd;
|
||||
|
||||
if(Debug.debugCanvas.enabled) {
|
||||
this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.bottom, edgeCandidatesBottom);
|
||||
this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom);
|
||||
} else {
|
||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.bottom, edgeCandidatesBottom);
|
||||
this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("\n\nuwu fucky wucky:", e, "\n\n")
|
||||
}
|
||||
|
||||
console.log("----------- returning: ", {
|
||||
edgeCandidatesTop: edgeCandidatesTop,
|
||||
edgeCandidatesTopCount: edgeCandidatesTop.count,
|
||||
edgeCandidatesBottom: edgeCandidatesBottom,
|
||||
edgeCandidatesBottomCount: edgeCandidatesBottom.count
|
||||
});
|
||||
|
||||
return {
|
||||
edgeCandidatesTop: edgeCandidatesTop,
|
||||
@ -556,7 +522,7 @@ class EdgeDetect{
|
||||
//
|
||||
// this is the shit we do to avoid function calls and one extra if sentence/code repetition
|
||||
// pretend I was drunk when I wrote this
|
||||
let tmpi, lastTmpI = 0, edgeDetectCount = 0, edgeDetectColsLeft = colsIn.length;
|
||||
let tmpI, edgeDetectCount = 0, edgeDetectColsLeft = colsIn.length;
|
||||
let tmpVal = 0;
|
||||
let increment, arrayStart, arrayEnd;
|
||||
|
||||
@ -586,9 +552,12 @@ class EdgeDetect{
|
||||
const colsTmp = new Array(colsIn.length);
|
||||
for (let i = 0; i < colsTmp.length; i++) {
|
||||
colsTmp[i] = {
|
||||
col: -1,
|
||||
blackFound: false,
|
||||
imageFound: false, // misleading name — also true if we ran over gradientSampleSize pixels from image
|
||||
// whether that actually count as an image depends on how aggressive gradientDetection is
|
||||
blackRow: -1,
|
||||
imageRow: -1,
|
||||
lastValue: -1,
|
||||
diffIndex: 0,
|
||||
diffs: new Array(this.settings.active.arDetect.blackbar.gradientSampleSize).fill(0)
|
||||
@ -628,9 +597,9 @@ class EdgeDetect{
|
||||
image[tmpI + 1] > this.blackbarThreshold ||
|
||||
image[tmpI + 2] > this.blackbarThreshold ){
|
||||
|
||||
colsOut[c].black = ~~(i / this.conf.canvasImageDataRowLength); // note — this value is off by one
|
||||
colsOut[c].col = colsIn[c].value;
|
||||
colsTmp[c].col = colsIn[c].value;
|
||||
colsTmp[c].blackFound = true;
|
||||
colsTmp[c].blackRow = ~~(loopCond.index.i / this.conf.canvasImageDataRowLength);
|
||||
|
||||
// prisili, da se zanka izvede še enkrat ter preveri,
|
||||
// ali trenuten piksel preseže tudi imageThreshold
|
||||
@ -653,7 +622,7 @@ class EdgeDetect{
|
||||
image[tmpI + 1] > this.imageThreshold ||
|
||||
image[tmpI + 2] > this.imageThreshold ){
|
||||
|
||||
colsOut[c].image = ~~(i / this.conf.canvasImageDataRowLength)
|
||||
colsTmp[c].imageRow = ~~(loopCond.index.i / this.conf.canvasImageDataRowLength)
|
||||
|
||||
|
||||
colsTmp[c].imageFound = true;
|
||||
@ -665,10 +634,10 @@ class EdgeDetect{
|
||||
|
||||
colsTmp[c].lastValue = image[tmpI] + image[tmpI+1] + image[tmpI+2];
|
||||
if (colsTmp[c].diffIndex !== 0) {
|
||||
colsTmp[c].diffs[colsTmp.diffIndex] = colsTmp[c].lastValue - colsTmp[c].diffs[diffIndex - 1];
|
||||
colsTmp[c].diffs[colsTmp[c].diffIndex] = colsTmp[c].lastValue - colsTmp[c].diffs[colsTmp[c].diffIndex - 1];
|
||||
}
|
||||
|
||||
cols[c].diffIndex++;
|
||||
colsTmp[c].diffIndex++;
|
||||
if (colsTmp[c].diffIndex > this.settings.active.arDetect.blackbar.gradientSampleSize) {
|
||||
colsTmp[c].imageFound = true;
|
||||
continue;
|
||||
@ -678,7 +647,87 @@ class EdgeDetect{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sprocesirajmo rezultate
|
||||
// let's process our results
|
||||
for (const c of colsTmp) {
|
||||
if (c.blackFound) {
|
||||
if (this.settings.active.arDetect.blackbar.antiGradientMode === AntiGradientMode.Disabled) {
|
||||
// if gradient detection is disabled, we treat such columns as detections/not gradient
|
||||
}
|
||||
if (c.imageFound) {
|
||||
if (c.imageRow - c.blackRow <= this.settings.active.arDetect.blackbar.gradientThreshold) {
|
||||
// this is within our margin of error. Colums like this are auto-accepted
|
||||
colsOut.push({
|
||||
col: c.col,
|
||||
black: c.blackRow
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
tmpVal = 0;
|
||||
|
||||
let i;
|
||||
// if we detected gradient, we'll analyse whether gradient is legit
|
||||
for (i = 0; i < c.diffIndex; i++) {
|
||||
tmpVal += c.diffs[i];
|
||||
|
||||
// if difference is negative, we aren't looking at a gradient
|
||||
if (c.diffs[i] < this.settings.active.arDetect.blackbar.gradientNegativeTreshold) {
|
||||
colsOut.push({
|
||||
col: c.col,
|
||||
black: c.blackRow
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
// if difference is too big, we assume we aren't looking at a gradient
|
||||
if (c.diffs[i] > this.settings.active.arDetect.blackbar.maxGradient) {
|
||||
colsOut.push({
|
||||
col: c.col,
|
||||
black: c.blackRow
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
// 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/
|
||||
// determining aspect ratio
|
||||
}
|
||||
|
||||
// if we didn't find any "not a gradient" diffs, we check for standard deviation
|
||||
if (i >= c.diffIndex && c.diffIndex > 1) {
|
||||
tmpVal /= c.diffIndex; // tmpVal is now average
|
||||
let squareSum = 0, stdev = 0;
|
||||
for (i = 0; i < c.diffIndex; i++) {
|
||||
squareSum += Math.pow((c.diffs[i] - tmpVal), 2)
|
||||
}
|
||||
stdev = Math.sqrt((squareSum / (c.diffIndex - 1)));
|
||||
|
||||
// if standard deviation is too big, we're not on a gradient (prolly)
|
||||
if (stdev > this.settings.active.arDetect.blackbar.gradientMaxSD) {
|
||||
colsOut.push({
|
||||
col: c.col,
|
||||
black: c.blackRow
|
||||
});
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we have blackbar but we haven't found a point that goes over imageTreshold.
|
||||
// how these cases are handled is determiend by what antiGradientMode we're using.
|
||||
// strict mode — treat as gradient. Lax mode — treat as not gradient
|
||||
if (this.settings.active.arDetect.blackbar.antiGradientMode === AntiGradientMode.Lax) {
|
||||
colsOut.push({
|
||||
col: c.col,
|
||||
black: c.blackRow
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_columnTest3_singleCol(image, top, bottom, colsIn, colsOut, reverseSearchDirection) {
|
||||
@ -1022,8 +1071,8 @@ class EdgeDetect{
|
||||
_imageTest(image, start, end, sampleOffset, edgeCandidates){
|
||||
var detections = 0;
|
||||
|
||||
for(var i = start; i < end; i += 4){
|
||||
if( image[i ] > this.blackbarThreshold ||
|
||||
for (var i = start; i < end; i += 4){
|
||||
if (image[i ] > this.blackbarThreshold ||
|
||||
image[i+1] > this.blackbarThreshold ||
|
||||
image[i+2] > this.blackbarThreshold ){
|
||||
++detections;
|
||||
|
Loading…
Reference in New Issue
Block a user