2016-07-17 14 views
7

Sadece this eğiticisini okudum ve bu örneği denedim. Bu yüzden kendi testlerim için web'den bir video indirdim. Tek yapmam gereken tüm şartlarChroma-anahtar efekti için RGB değerini doğru olarak nasıl filtreleyebilir

BURADA öğretici örnek olarak filtreleme dışarı sarı (sarı değil sanırım) renk olarak örnek

computeFrame: function() { 
    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); 
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height); 
    let l = frame.data.length/4; 

    for (let i = 0; i < l; i++) { 
     let r = frame.data[i * 4 + 0]; 
     let g = frame.data[i * 4 + 1]; 
     let b = frame.data[i * 4 + 2]; 
     if (g > 100 && r > 100 && b < 43) 
     frame.data[i * 4 + 3] = 0; 
    } 
    this.ctx2.putImageData(frame, 0, 0); 
    return; 
    } 

dan örnek kod ise de rgb değerlerini çimdik olduğunu. İndirdiğim örnek video yeşil arka plan kullanıyor. Bu yüzden istenilen sonucu elde etmek için rgb değerini değiştirdim.

Birden çok denemeden sonra bunu elde etmeyi başardım.

enter image description here

Şimdi bilmek istediğim ben doğru mükemmel tahmin olmadan yeşil ekran (veya başka bir ekran) filtreleyebilirsiniz nasıl. Ya da rastgele ayarlanmış değerler.

Sadece tahmin edebilmek için doğru bir şekilde doğru olması saatler alıyor. Ve bu gerçek bir dünya uygulaması ile sadece bir örnektir. Belki daha fazla alabilir.

NOT: örnek şimdilik Firefox'ta çalışıyor ..

cevap

3

Muhtemelen sadece daha iyi bir algoritma gerekir. İşte bir, mükemmel değil, ama çok daha kolay bir şekilde değiştirebilirsiniz.

just do it bro

Temel olarak bir colorpicker gerekir ve videodan aydınlık ve en karanlık değerlerini almak (l_ RGB değerlerini koyarak ve sırasıyla değişkenleri D_) sadece edeceğiz. İhtiyacınız varsa, toleransı biraz ayarlayabilirsiniz, ancak renk seçici ile farklı alanları seçerek l_ ve r_ değerlerini elde etmek size daha iyi bir anahtar verecektir. performans önemli değilse

let l_r = 131, 
    l_g = 190, 
    l_b = 137, 

    d_r = 74, 
    d_g = 148, 
    d_b = 100; 

let tolerance = 0.05; 

let processor = { 
    timerCallback: function() { 
    if (this.video.paused || this.video.ended) { 
     return; 
    } 
    this.computeFrame(); 
    let self = this; 
    setTimeout(function() { 
     self.timerCallback(); 
     }, 0); 
    }, 

    doLoad: function() { 
    this.video = document.getElementById("video"); 
    this.c1 = document.getElementById("c1"); 
    this.ctx1 = this.c1.getContext("2d"); 
    this.c2 = document.getElementById("c2"); 
    this.ctx2 = this.c2.getContext("2d"); 
    let self = this; 
    this.video.addEventListener("play", function() { 
     self.width = self.video.videoWidth; 
     self.height = self.video.videoHeight; 
     self.timerCallback(); 
     }, false); 
    }, 

    calculateDistance: function(c, min, max) { 
     if(c < min) return min - c; 
     if(c > max) return c - max; 

     return 0; 
    }, 

    computeFrame: function() { 
    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); 
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height); 
     let l = frame.data.length/4; 

    for (let i = 0; i < l; i++) { 
     let _r = frame.data[i * 4 + 0]; 
     let _g = frame.data[i * 4 + 1]; 
     let _b = frame.data[i * 4 + 2]; 

     let difference = this.calculateDistance(_r, d_r, l_r) + 
         this.calculateDistance(_g, d_g, l_g) + 
         this.calculateDistance(_b, d_b, l_b); 
     difference /= (255 * 3); // convert to percent 
     if (difference < tolerance) 
     frame.data[i * 4 + 3] = 0; 
    } 
    this.ctx2.putImageData(frame, 0, 0); 
    return; 
    } 
}; 
// :/ 
+0

Gerçekten güzel bir örnek .. ama hala sorunlar bulmaktan yaşıyorum ..Visually i RGBvalues ​​bakarak karanlık ve aydınlık tonları belirleyebilir nasıl .. aynı görünüyor. –

+0

@Akash Kumar merkeze doğru, yeşil ekranın köşelerinden neredeyse her zaman daha parlaktır. Hala filtre uygulanmayan yeşil renk varsa, bunu bırakın ve yeni ışık veya karanlık olarak kullanın. Birkaç geçiş yapabilir, ancak sadece birkaç dakika sürmelidir. – Entity

+0

anladı .. toleransı biraz ayarlamak gerekiyor .. –

1

, o zaman örneğin başka bir renk uzayında işe yarayabilir HSV. Sol üst pikseli referans olarak kullanabilirsiniz.

Referans noktasının renk tonu değerini diğer piksel değerleriyle karşılaştırırsınız ve doygunluk ve değer kullanarak belirli bir eşiği ve koyu ve açık alanları aşan tüm pikselleri hariç tutarsınız.

Bu, nasıl renk kanamasından tamamen kurtulmuyorsa, renk doğru/desatürasyon yapmak gerekebilir.

function rgb2hsv() { 
    var rr, gg, bb, 
     r = arguments[0]/255, 
     g = arguments[1]/255, 
     b = arguments[2]/255, 
     h, s, 
     v = Math.max(r, g, b), 
     diff = v - Math.min(r, g, b), 
     diffc = function(c){ 
      return (v - c)/6/diff + 1/2; 
     }; 

    if (diff == 0) { 
     h = s = 0; 
    } else { 
     s = diff/v; 
     rr = diffc(r); 
     gg = diffc(g); 
     bb = diffc(b); 

     if (r === v) { 
      h = bb - gg; 
     }else if (g === v) { 
      h = (1/3) + rr - bb; 
     }else if (b === v) { 
      h = (2/3) + gg - rr; 
     } 
     if (h < 0) { 
      h += 1; 
     }else if (h > 1) { 
      h -= 1; 
     } 
    } 
    return { 
     h: Math.round(h * 360), 
     s: Math.round(s * 100), 
     v: Math.round(v * 100) 
    }; 
} 


let processor = { 
    timerCallback: function() { 
    if (this.video.paused || this.video.ended) { 
     return; 
    } 
    this.computeFrame(); 
    let self = this; 
    setTimeout(function() { 
     self.timerCallback(); 
     }, 0); 
    }, 

    doLoad: function() { 
    this.video = document.getElementById("video"); 
    this.c1 = document.getElementById("c1"); 
    this.ctx1 = this.c1.getContext("2d"); 
    this.c2 = document.getElementById("c2"); 
    this.ctx2 = this.c2.getContext("2d"); 
    let self = this; 
    this.video.addEventListener("play", function() { 
     self.width = self.video.videoWidth/2; 
     self.height = self.video.videoHeight/2; 
     self.timerCallback(); 
     }, false); 
    }, 

    computeFrame: function() { 
    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); 
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height); 
     let l = frame.data.length/4; 


    let reference = rgb2hsv(frame.data[0], frame.data[1], frame.data[2]); 

    for (let i = 0; i < l; i++) { 
     let r = frame.data[i * 4 + 0]; 
     let g = frame.data[i * 4 + 1]; 
     let b = frame.data[i * 4 + 2]; 
     let hsv = rgb2hsv(r, g, b); 

     let hueDifference = Math.abs(hsv.h - reference.h); 

     if(hueDifference < 20 && hsv.v > 50 && hsv.s > 50) { 
     frame.data[i * 4 + 3] = 0; 
     } 


    } 
    this.ctx2.putImageData(frame, 0, 0); 
    return; 
    } 
}; 
+0

Performans önemli değil. ama yine de deneyeceğim. –

İlgili konular