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
|
// 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)
|
// 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
|
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: {
|
arChange: {
|
||||||
|
@ -147,14 +147,16 @@ var _pd_checkPlayerSizeChange = function(){
|
|||||||
if(GlobalVars.playerDimensions.element == undefined)
|
if(GlobalVars.playerDimensions.element == undefined)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// if(GlobalVars.playerDimensions.fullscreen){
|
|
||||||
// return ! _pd_isFullScreen();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if(GlobalVars.playerDimensions.width != GlobalVars.playerDimensions.element.offsetWidth || GlobalVars.playerDimensions.height != GlobalVars.playerDimensions.element.offsetHeight ){
|
if(GlobalVars.playerDimensions.width != GlobalVars.playerDimensions.element.offsetWidth || GlobalVars.playerDimensions.height != GlobalVars.playerDimensions.element.offsetHeight ){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if(GlobalVars.playerDimensions.fullscreen){
|
||||||
|
// return ! _pd_isFullScreen();
|
||||||
|
// }
|
||||||
|
|
||||||
return false;
|
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)
|
// per video/pageload instead of every time letterbox goes away (this can happen more than once per vid)
|
||||||
GlobalVars.arDetect.noLetterboxCanvasReset = false;
|
GlobalVars.arDetect.noLetterboxCanvasReset = false;
|
||||||
|
|
||||||
|
console.log("ping!")
|
||||||
|
|
||||||
|
|
||||||
// let's do a quick test to see if we're on a black frame
|
// let's do a quick test to see if we're on a black frame
|
||||||
// TODO: reimplement but with less bullshit
|
// 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.
|
// pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa.
|
||||||
// let's see where black bars end.
|
// let's see where black bars end.
|
||||||
GlobalVars.sampleCols_current = sampleCols.length;
|
GlobalVars.sampleCols_current = sampleCols.length;
|
||||||
@ -537,11 +558,31 @@ 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);
|
// 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"){
|
if(edgePost.status == "ar_known"){
|
||||||
_ard_processAr(GlobalVars.video, GlobalVars.canvas.width, GlobalVars.canvas.height, edgePost.blackbarWidth, null, fallbackMode);
|
// 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;;
|
||||||
|
|
||||||
// we also know edges for guardline, so set them
|
if(edgePost.guardLineTop != null){
|
||||||
GlobalVars.arDetect.guardLine.top = edgePost.guardLineTop;
|
var row = edgePost.guardLineTop + ~~(GlobalVars.canvas.height * ExtensionConf.arDetect.textLineTest.testRowOffset);
|
||||||
GlobalVars.arDetect.guardLine.bottom = edgePost.guardLineBottom;
|
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;
|
delete image;
|
||||||
triggerTimeout = _ard_getTimeout(baseTimeout, startTime);
|
triggerTimeout = _ard_getTimeout(baseTimeout, startTime);
|
||||||
@ -558,66 +599,160 @@ var _ard_vdraw_but_for_reals = function() {
|
|||||||
delete image;
|
delete image;
|
||||||
}
|
}
|
||||||
|
|
||||||
var getBlackRatioEstimate = function(image){
|
var pillarTest = function(image){
|
||||||
var blackbarTreshold, upper, lower;
|
// 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;
|
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 rowStart = middleRowStart << 2;
|
||||||
var rowSpacing = ~~(GlobalVars.canvas.height * spread / sampleRows);
|
var midpoint = (middleRowStart + (GlobalVars.canvas.width >> 1)) << 2
|
||||||
var colSpacing = ~~(GlobalVars.canvas.width / sampleCols) >> 2;
|
var rowEnd = middleRowEnd << 2;
|
||||||
var colOffset = colSpacing >> 1;
|
|
||||||
|
|
||||||
var rowStart;
|
var edge_left = -1; edge_right = -1;
|
||||||
|
|
||||||
var blackCount = 0, blackRatio, totalSamples = sampleCols * (sampleCols - 1);
|
// preverimo na levi strani
|
||||||
|
// let's check for edge on the left side
|
||||||
for(var i = 0; i < sampleRows; i++){
|
for(var i = rowStart; i < midpoint; i+=4){
|
||||||
rowStart = ((rowOffset * GlobalVars.canvas.width) << 2) + colOffset;
|
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
||||||
colOffset = rowStart;
|
edge_left = (i - rowStart) >> 2;
|
||||||
|
break;
|
||||||
for(var j = 1; j < sampleCols; j++){
|
|
||||||
if(image[colOffset] > blackbarTreshold || image[colOffset+1] > blackbarTreshold || image[colOffset+2] > blackbarTreshold){
|
|
||||||
blackCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
colOffset += colSpacing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rowOffset += rowSpacing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// preverimo na desni strani
|
||||||
rowStart = ((edge_upper * GlobalVars.canvas.width) << 2) + offset;
|
// check on the right
|
||||||
rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2);
|
for(var i = rowEnd; i > midpoint; i-= 4){
|
||||||
|
|
||||||
for(var i = rowStart; i < rowEnd; i+=4){
|
|
||||||
|
|
||||||
// we track sections that go over what's supposed to be a black line, so we can suggest more
|
|
||||||
// columns to sample
|
|
||||||
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
||||||
if(firstOffender < 0){
|
edge_right = GlobalVars.canvas.width - ((i - rowStart) >> 2);
|
||||||
firstOffender = (i * 0.25) - rowStart;
|
break;
|
||||||
offenderCount++;
|
}
|
||||||
offenders.push({x: firstOffender, width: 1})
|
}
|
||||||
|
|
||||||
|
// č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{
|
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{
|
else{
|
||||||
// is that a black pixel again? Let's reset the 'first offender'
|
if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){
|
||||||
firstOffender = -1;
|
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){
|
var _ard_guardLineCheck = function(image, fallbackMode){
|
||||||
// this test tests for whether we crop too aggressively
|
// 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
|
// 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
|
// check both rows - by the rules and definitions, we shouldn't go out of bounds here. no need to check, then
|
||||||
|
|
||||||
// if(fallbackMode){
|
// if(fallbackMode){
|
||||||
// var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx;
|
// var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx;
|
||||||
// var edge_lower = GlobalVars.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1;
|
// var edge_lower = GlobalVars.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1;
|
||||||
// }
|
// }
|
||||||
// else{
|
// else{
|
||||||
var edge_upper = edges.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx;
|
var edge_upper = edges.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx;
|
||||||
var edge_lower = edges.bottom - 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
|
// 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)
|
// 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
|
// če za vsako stran (zgoraj in spodaj) poznamo vsaj enega kandidata, potem lahko preverimo nekaj
|
||||||
// stvari
|
// stvari
|
||||||
|
Loading…
Reference in New Issue
Block a user