p5.js | Качество изображения, полученного с канала камеры, ниже, чем фактический канал камеры?

#javascript #video #p5.js

Вопрос:

С помощью приведенного ниже кода качество видео, поступающего с камеры моего Mac и показанного внутри <video> , отличное.

Однако качество кадра, который я снимаю и показываю на холсте p5, довольно низкое, темное и зернистое. Почему это так и могу ли я это исправить ?

 function setup() {
  let canvas = createCanvas(canvasSize, canvasSize)
  canvas.elt.width = canvasSize
  canvas.elt.height = canvasSize
  video = createCapture(VIDEO)
}

let PAUSE = false

async function draw() {

  if (video amp;amp; video.loadedmetadata) {

    if (!PAUSE) {
      // the quality of this image is much lower than what is shown inside p5's <video>
      image(video.get(), 0, 0, canvasSize, canvasSize, x, y, canvasSize, canvasSize)

      PAUSE = true

    }

  }

}
 

Ответ №1:

Я понял, в чем была проблема.

Это произошло не из-за того , что я установил canvas.elt.width и canvas.elt.height , хотя их установка действительно избыточна.

Это потому, что в коде, показанном в операции, я снимал самый первый кадр, а это слишком рано, поэтому самый первый кадр все еще темный и размытый. По-видимому, первые несколько кадров, поступающих с камеры, похожи на это.

Если я дам своему коду задержку, например, на 5 секунд, то кадр, который он захватит, будет такого же качества, как и тот, который поступает из видеопотока.

 let video
let canvasWidth = 400

// set this to 10 on https://editor.p5js.org/ and you'll see the problem
const DELAY = 5000

function setup() {
  let canvas = createCanvas(canvasWidth, canvasWidth)
  canvas.elt.width = canvasWidth // redundant
  canvas.elt.height = canvasWidth // redundant
  video = createCapture(VIDEO)
}

let PAUSE = false
let start = Date.now()

async function draw() {
  let delay = Date.now() - start

  if (video amp;amp; video.loadedmetadata) {

    if (delay > DELAY amp;amp; !PAUSE) {
      PAUSE = true
      
      let x = Math.round((video.width / 2) - (canvasWidth / 2))
      let y = Math.round((video.height / 2) - (canvasWidth / 2))

      // the quality of this image is now perfect
      image(video.get(), 0, 0, canvasWidth, canvasWidth, x, y, canvasWidth, canvasWidth)
    }

  }

}
 

Ответ №2:

Вы не должны устанавливать ширину/высоту таким образом. Это испортит размер на дисплеях с высоким разрешением и приведет к тому, что ваше изображение будет выглядеть растянутым и размытым.

 const canvasSize = 500;

function setup() {
  let canvas = createCanvas(canvasSize, canvasSize)
  // Don't do this, it will mess up the sizing on high DPI displays:
  // canvas.elt.width = canvasSize
  // canvas.elt.height = canvasSize
  video = createCapture(VIDEO)
}

let PAUSE = false;

function draw() {
  if (video amp;amp; video.loadedmetadata) {
    if (!PAUSE) {
      // the quality of this image is much lower than what is shown inside p5's <video>
      image(video.get(), 0, 0, canvasSize, canvasSize, 0, 0, canvasSize, canvasSize)
    }
  }
}

function keyPressed() {
  if (key === 'p') {
    PAUSE = !PAUSE;
  }
}
 

С помощью этого кода я приостановил видео, которое отображалось на p5.js а затем сделал снимок экрана. Версия видео, отображаемого на p5.js стирка холста неотличима от живого видео.