如何准确过滤RGB值以获得色键效果 [英] How to accurately filter RGB value for chroma-key effect

查看:125
本文介绍了如何准确过滤RGB值以获得色键效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚阅读了教程,并尝试了这个例子.因此,我从网上下载了一个视频进行自己的测试.我要做的就是在if条件下调整rgb值

I just read this tutorial and tried this example. So I downloaded a video from web for my own testing. All I have to do is tweak rgb values in if conditions

HERE是示例中的示例代码

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;
  }

在教程示例中,它过滤掉了黄色(我猜不是黄色).我下载的示例视频使用绿色背景.所以我在if条件下调整了rgb值以获得所需的结果

In the tutorial example its filtering out yellow(not yellow I guess) color. The sample video I downloaded uses green background. So I tweaked rgb value in if condition to get desired results

经过多次尝试,我设法做到了.

After multiple tries, I managed to get this.

现在我想知道的是如何准确无误地准确过滤出绿色屏幕(或其他任何屏幕).或随机调整值.

Now what I want to know is how can I accurately filter out green screen (or any other screen)perfectly without guessing. Or randomly tweaking values.

仅需花费数小时即可使其完全正确.这只是一个具有实际应用程序的示例.可能还需要更多时间.

With just guessing it take hours to get it perfectly right. And this is just a sample with a real world application. It can take maybe more.

注意:该示例目前正在Firefox中运行.

推荐答案

您可能只需要一个更好的算法.这是一个,它并不完美,但是您可以更轻松地对其进行调整.

You probably just need a better algorithm. Here's one, it's not perfect, but you can tweak it a lot easier.

基本上,您只需要一个颜色选择器,然后从视频中选择最亮和最暗的值(分别将RGB值分别放入l_和d_变量中)即可.您可以根据需要稍微调整公差,但是通过用颜色选择器选择不同的区域来正确设置l_和r_值将为您提供更好的关键.

Basically you'll just need a colorpicker, and pick the lightest and darkest values from the video (putting the RGB values in the l_ and d_ variables respectively). You can adjust the tolerance a little bit if you need to, but getting the l_ and r_ values just right by picking different areas with the color picker will give you a better key.

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;
  }
};
// :/ 

这篇关于如何准确过滤RGB值以获得色键效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆