Tried implementing some checks that would prevent aspect ratio from changing if our edge candidate is text on black background.
This commit is contained in:
parent
3740f2c487
commit
59d741b8a5
@ -62,6 +62,18 @@ var ExtensionConf = {
|
||||
// continue with search. It's pointless, because black edge is higher/lower than we
|
||||
// are now. (NOTE: keep this less than 1 in case we implement logo detection)
|
||||
edgeTolerancePx: 1, // tests for edge detection are performed this far away from detected row
|
||||
},
|
||||
pillarTest: {
|
||||
ignoreThinPillarsPx: 5, // ignore pillars that are less than this many pixels thick.
|
||||
allowMisaligned: 0.05 // left and right edge can vary this much (%)
|
||||
},
|
||||
textLineTest: {
|
||||
nonTextPulse: 0.10, // if a single continuous pulse has this many non-black pixels, we aren't dealing
|
||||
// with text. This value is relative to canvas width (%)
|
||||
pulsesToConfirm: 10, // this is a treshold to confirm we're seeing text.
|
||||
pulsesToConfirmIfHalfBlack: 5, // this is the treshold to confirm we're seeing text if longest black pulse
|
||||
// is over 50% of the canvas width
|
||||
testRowOffset: 0.02 // we test this % of height from detected edge
|
||||
}
|
||||
},
|
||||
arChange: {
|
||||
|
@ -147,14 +147,16 @@ var _pd_checkPlayerSizeChange = function(){
|
||||
if(GlobalVars.playerDimensions.element == undefined)
|
||||
return true;
|
||||
|
||||
// if(GlobalVars.playerDimensions.fullscreen){
|
||||
// return ! _pd_isFullScreen();
|
||||
// }
|
||||
|
||||
|
||||
if(GlobalVars.playerDimensions.width != GlobalVars.playerDimensions.element.offsetWidth || GlobalVars.playerDimensions.height != GlobalVars.playerDimensions.element.offsetHeight ){
|
||||
return true;
|
||||
}
|
||||
|
||||
// if(GlobalVars.playerDimensions.fullscreen){
|
||||
// return ! _pd_isFullScreen();
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -475,6 +475,9 @@ var _ard_vdraw_but_for_reals = function() {
|
||||
// per video/pageload instead of every time letterbox goes away (this can happen more than once per vid)
|
||||
GlobalVars.arDetect.noLetterboxCanvasReset = false;
|
||||
|
||||
console.log("ping!")
|
||||
|
||||
|
||||
// let's do a quick test to see if we're on a black frame
|
||||
// TODO: reimplement but with less bullshit
|
||||
|
||||
@ -524,6 +527,24 @@ var _ard_vdraw_but_for_reals = function() {
|
||||
|
||||
}
|
||||
|
||||
// će se razmerje stranic spreminja iz ožjega na širšega, potem najprej poglejmo za prisotnostjo navpičnih črnih obrob.
|
||||
// če so prisotne navpične obrobe tudi na levi in desni strani, potlej obstaja možnost, da gre za logo na črnem ozadju.
|
||||
// v tem primeru obstaja nevarnost, da porežemo preveč. Ker obstaja dovolj velika možnost, da bi porezali preveč, rajši
|
||||
// ne naredimo ničesar.
|
||||
//
|
||||
// If aspect ratio changes from narrower to wider, we first check for presence of pillarbox. Presence of pillarbox indicates
|
||||
// a chance of a logo on black background. We could cut easily cut too much. Because there's a somewhat significant chance
|
||||
// that we will cut too much, we rather avoid doing anything at all. There's gonna be a next chance.
|
||||
if(! imageDetectResult){
|
||||
if(pillarTest(image)){
|
||||
console.log("pillarboxing, doing jack shit")
|
||||
delete image;
|
||||
triggerTimeout = _ard_getTimeout(baseTimeout, startTime);
|
||||
_ard_vdraw(triggerTimeout);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa.
|
||||
// let's see where black bars end.
|
||||
GlobalVars.sampleCols_current = sampleCols.length;
|
||||
@ -537,12 +558,32 @@ var _ard_vdraw_but_for_reals = function() {
|
||||
// console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", GlobalVars.arDetect.blackLevel + ExtensionConf.arDetect.blackbarTreshold);
|
||||
|
||||
if(edgePost.status == "ar_known"){
|
||||
_ard_processAr(GlobalVars.video, GlobalVars.canvas.width, GlobalVars.canvas.height, edgePost.blackbarWidth, null, fallbackMode);
|
||||
|
||||
// we also know edges for guardline, so set them
|
||||
GlobalVars.arDetect.guardLine.top = edgePost.guardLineTop;
|
||||
GlobalVars.arDetect.guardLine.bottom = edgePost.guardLineBottom;
|
||||
// zaznali smo rob — vendar pa moramo pred obdelavo še preveriti, ali ni "rob" slučajno besedilo. Če smo kot rob pofočkali
|
||||
// besedilo, potem to ni veljaven rob. Razmerja stranic se zato ne bomo pipali.
|
||||
// we detected an edge — but before we process it, we need to check if the "edge" isn't actually some text. If the detected
|
||||
// edge is actually some text on black background, we shouldn't touch the aspect ratio. Whatever we detected is invalid.
|
||||
var textEdge = false;;
|
||||
|
||||
if(edgePost.guardLineTop != null){
|
||||
var row = edgePost.guardLineTop + ~~(GlobalVars.canvas.height * ExtensionConf.arDetect.textLineTest.testRowOffset);
|
||||
textEdge |= textLineTest(image, row);
|
||||
}
|
||||
if(edgePost.guardLineTop != null){
|
||||
var row = edgePost.guardLineTop - ~~(GlobalVars.canvas.height * ExtensionConf.arDetect.textLineTest.testRowOffset);
|
||||
textEdge |= textLineTest(image, row);
|
||||
}
|
||||
|
||||
if(!textEdge){
|
||||
_ard_processAr(GlobalVars.video, GlobalVars.canvas.width, GlobalVars.canvas.height, edgePost.blackbarWidth, null, fallbackMode);
|
||||
|
||||
// we also know edges for guardline, so set them
|
||||
GlobalVars.arDetect.guardLine.top = edgePost.guardLineTop;
|
||||
GlobalVars.arDetect.guardLine.bottom = edgePost.guardLineBottom;
|
||||
}
|
||||
else{
|
||||
console.log("detected text on edges, dooing nothing")
|
||||
}
|
||||
|
||||
delete image;
|
||||
triggerTimeout = _ard_getTimeout(baseTimeout, startTime);
|
||||
_ard_vdraw(triggerTimeout); //no letterbox, no problem
|
||||
@ -558,66 +599,160 @@ var _ard_vdraw_but_for_reals = function() {
|
||||
delete image;
|
||||
}
|
||||
|
||||
var getBlackRatioEstimate = function(image){
|
||||
var blackbarTreshold, upper, lower;
|
||||
var pillarTest = function(image){
|
||||
// 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.
|
||||
// <==XX(::::}----{::::)XX==>
|
||||
// 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.
|
||||
// we also return true if we detect too much black
|
||||
|
||||
var blackbarTreshold, upper, lower;
|
||||
blackbarTreshold = GlobalVars.arDetect.blackLevel + ExtensionConf.arDetect.blackbarTreshold;
|
||||
|
||||
var sampleRows = 5;
|
||||
var sampleCols = 10; // has 1 more than actually
|
||||
|
||||
var spread = 0.4; // how far from middle the samples go
|
||||
var middleRowStart = (GlobalVars.canvas.height >> 1) * GlobalVars.canvas.width;
|
||||
var middleRowEnd = middleRowStart + GlobalVars.canvas.width - 1;
|
||||
|
||||
var rowOffset = ~~(GlobalVars.canvas.height / (spread >> 1));
|
||||
var rowSpacing = ~~(GlobalVars.canvas.height * spread / sampleRows);
|
||||
var colSpacing = ~~(GlobalVars.canvas.width / sampleCols) >> 2;
|
||||
var colOffset = colSpacing >> 1;
|
||||
var rowStart = middleRowStart << 2;
|
||||
var midpoint = (middleRowStart + (GlobalVars.canvas.width >> 1)) << 2
|
||||
var rowEnd = middleRowEnd << 2;
|
||||
|
||||
var rowStart;
|
||||
var edge_left = -1; edge_right = -1;
|
||||
|
||||
var blackCount = 0, blackRatio, totalSamples = sampleCols * (sampleCols - 1);
|
||||
|
||||
for(var i = 0; i < sampleRows; i++){
|
||||
rowStart = ((rowOffset * GlobalVars.canvas.width) << 2) + colOffset;
|
||||
colOffset = rowStart;
|
||||
|
||||
for(var j = 1; j < sampleCols; j++){
|
||||
if(image[colOffset] > blackbarTreshold || image[colOffset+1] > blackbarTreshold || image[colOffset+2] > blackbarTreshold){
|
||||
blackCount++
|
||||
}
|
||||
|
||||
colOffset += colSpacing;
|
||||
// preverimo na levi strani
|
||||
// let's check for edge on the left side
|
||||
for(var i = rowStart; i < midpoint; i+=4){
|
||||
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
||||
edge_left = (i - rowStart) >> 2;
|
||||
break;
|
||||
}
|
||||
|
||||
rowOffset += rowSpacing;
|
||||
}
|
||||
|
||||
|
||||
rowStart = ((edge_upper * GlobalVars.canvas.width) << 2) + offset;
|
||||
rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2);
|
||||
|
||||
for(var i = rowStart; i < rowEnd; i+=4){
|
||||
|
||||
// we track sections that go over what's supposed to be a black line, so we can suggest more
|
||||
// columns to sample
|
||||
// preverimo na desni strani
|
||||
// check on the right
|
||||
for(var i = rowEnd; i > midpoint; i-= 4){
|
||||
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
||||
if(firstOffender < 0){
|
||||
firstOffender = (i * 0.25) - rowStart;
|
||||
offenderCount++;
|
||||
offenders.push({x: firstOffender, width: 1})
|
||||
edge_right = GlobalVars.canvas.width - ((i - rowStart) >> 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// če je katerikoli -1, potem imamo preveč črnine
|
||||
// we probably have too much black if either of those two is -1
|
||||
if(edge_left == -1 || edge_right == -1){
|
||||
return true;
|
||||
}
|
||||
|
||||
// če sta oba robova v mejah merske napake, potem vrnemo 'false'
|
||||
// if both edges resemble rounding error, we retunr 'false'
|
||||
if(edge_left < ExtensionConf.arDetect.pillarTest.ignoreThinPillarsPx && edge_right < ExtensionConf.arDetect.pillarTest.ignoreThinPillarsPx){
|
||||
return false;
|
||||
}
|
||||
|
||||
var edgeError = ExtensionConf.arDetect.pillarTest.allowMisaligned;
|
||||
var error_low = 1 - edgeError;
|
||||
var 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
|
||||
// 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
|
||||
if( (edge_left * error_low) < edge_right &&
|
||||
(edge_left * error_hi) > edge_right ){
|
||||
return true;
|
||||
}
|
||||
|
||||
// če se ne zgodi nič od neštetega, potem nismo našli problemov
|
||||
// if none of the above, we haven't found a problem
|
||||
return false;
|
||||
}
|
||||
|
||||
var textLineTest = function(image, row){
|
||||
// preverimo, če vrstica vsebuje besedilo na črnem ozadju. Če ob pregledu vrstice naletimo na veliko sprememb
|
||||
// iz črnega v ne-črno, potem obstaja možnost, da gledamo besedilo. Prisotnost take vrstice je lahko znak, da
|
||||
// zaznano razmerje stranic ni veljavno
|
||||
//
|
||||
// vrne 'true' če zazna text, 'false' drugače.
|
||||
//
|
||||
//
|
||||
// check if line contains any text. If line scan reveals a lot of changes from black to non-black there's a
|
||||
// chance we're looking at text on a black background. If we detect text near what we think is an edge of the
|
||||
// video, there's a good chance we're about to incorrectly adjust the aspect ratio.
|
||||
//
|
||||
// returns 'true' if text is detected, 'false' otherwise
|
||||
|
||||
var blackbarTreshold = GlobalVars.arDetect.blackLevel + ExtensionConf.arDetect.blackbarTreshold;
|
||||
var nontextTreshold = GlobalVars.canvas.width * ExtensionConf.arDetect.textLineTest.nonTextPulse;
|
||||
|
||||
var rowStart = (row * GlobalVars.canvas.width) << 2;
|
||||
var rowEnd = rowStart + (GlobalVars.canvas.width << 2);
|
||||
|
||||
var pulse = false;
|
||||
var currentPulseLength = 0, pulseCount = 0;
|
||||
var pulses = [];
|
||||
var longestBlack = 0;
|
||||
|
||||
// preglejmo vrstico
|
||||
// analyse the row
|
||||
for(var i = rowStart; i < rowEnd; i+= 4){
|
||||
if(pulse){
|
||||
if(image[i] < blackbarTreshold || image[i+1] < blackbarTreshold || image[i+2] < blackbarTreshold){
|
||||
// pulses.push(currentPulseLength);
|
||||
pulseCount++;
|
||||
pulse = false;
|
||||
currentPulseLength = 0;
|
||||
}
|
||||
else{
|
||||
offenders[offenderCount].width++
|
||||
currentPulseLength++;
|
||||
|
||||
// če najdemo dovolj dolgo zaporedje ne-črnih točk, potem vrnemo 'false' — dobili smo legitimen rob
|
||||
// if we find long enough uninterrupted line of non-black point, we fail the test. We found a legit edge.
|
||||
if(currentPulseLength > nontextTreshold){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
// is that a black pixel again? Let's reset the 'first offender'
|
||||
firstOffender = -1;
|
||||
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
||||
if(currentPulseLength > longestBlack){
|
||||
longestBlack = currentPulseLength;
|
||||
}
|
||||
pulse = true;
|
||||
currentPulseLength = 0;
|
||||
}
|
||||
else{
|
||||
currentPulseLength++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(pulse){
|
||||
pulseCount++;
|
||||
// pulses.push(currentPulseLength);
|
||||
}
|
||||
|
||||
// pregledamo rezultate:
|
||||
// analyse the results
|
||||
console.log("pulse test:\n\npulses:", pulseCount, "longest black:", longestBlack);
|
||||
|
||||
// če smo zaznali dovolj pulzov, potem vrnemo res
|
||||
// if we detected enough pulses, we return true
|
||||
if(pulseCount > ExtensionConf.arDetect.textLineTest.pulsesToConfirm){
|
||||
return true;
|
||||
}
|
||||
|
||||
// če je najdaljša neprekinjena črta črnih pikslov širša od polovice širine je merilo za zaznavanje
|
||||
// besedila rahlo milejše
|
||||
// if the longest uninterrupted line of black pixels is wider than half the width, we use a more
|
||||
// forgiving standard for determining if we found text
|
||||
if( longestBlack > (GlobalVars.canvas.width >> 1) &&
|
||||
pulseCount > ExtensionConf.arDetect.textLineTest.pulsesToConfirmIfHalfBlack ){
|
||||
return true;
|
||||
}
|
||||
|
||||
// če pridemo do sem, potem besedilo ni bilo zaznano
|
||||
// if we're here, no text was detected
|
||||
return false;
|
||||
}
|
||||
|
||||
var _ard_guardLineCheck = function(image, fallbackMode){
|
||||
// this test tests for whether we crop too aggressively
|
||||
@ -998,14 +1133,14 @@ var _ard_guardLineImageDetect = function(image, fallbackMode){
|
||||
// preglejmo obe vrstici - tukaj po pravilih ne bi smeli iti prek mej platna. ne rabimo preverjati
|
||||
// check both rows - by the rules and definitions, we shouldn't go out of bounds here. no need to check, then
|
||||
|
||||
// if(fallbackMode){
|
||||
// var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx;
|
||||
// var edge_lower = GlobalVars.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1;
|
||||
// }
|
||||
// else{
|
||||
var edge_upper = edges.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx;
|
||||
var edge_lower = edges.bottom - ExtensionConf.arDetect.guardLine.edgeTolerancePx;
|
||||
// }
|
||||
// if(fallbackMode){
|
||||
// var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx;
|
||||
// var edge_lower = GlobalVars.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1;
|
||||
// }
|
||||
// else{
|
||||
var edge_upper = edges.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx;
|
||||
var edge_lower = edges.bottom - ExtensionConf.arDetect.guardLine.edgeTolerancePx;
|
||||
// }
|
||||
|
||||
// koliko pikslov rabimo zaznati, da je ta funkcija uspe. Tu dovoljujemo tudi, da so vsi piksli na enem
|
||||
// robu (eden izmed robov je lahko v celoti črn)
|
||||
@ -1073,7 +1208,7 @@ var _ard_edgePostprocess = function(edges, canvasHeight){
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("count top:",edges.edgeCandidatesTopCount, "edges:", edges, "edgesTop[]", edgesTop);
|
||||
// console.log("count top:",edges.edgeCandidatesTopCount, "edges:", edges, "edgesTop[]", edgesTop);
|
||||
|
||||
// če za vsako stran (zgoraj in spodaj) poznamo vsaj enega kandidata, potem lahko preverimo nekaj
|
||||
// stvari
|
||||
|
Loading…
Reference in New Issue
Block a user