p5.js |从相机馈送捕获的图像质量低于实际相机馈送?
p5.js | Quality of image captured from camera feed, lower than actual camera feed?
使用下面的代码,来自我的 Mac 相机并在 <video>
中显示的视频质量非常好。
然而,我在 p5 canvas 中捕获和显示的帧的质量非常低、暗且有颗粒感。为什么会这样,我可以解决它吗?
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 && 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
}
}
}
你不应该这样设置 width/height。这会弄乱高 DPI 显示器的大小,并导致您的图像显得拉伸和模糊。
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 && 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 canvas 上显示的视频版本与实时视频没有区别。
我找到问题所在了。
不是因为我设置了canvas.elt.width
和canvas.elt.height
,尽管设置它们确实是多余的。
这是因为在 OP 中显示的代码中,我捕获了 第一帧 而这 太快了 所以第一帧框架仍然是黑暗和模糊的。显然从相机传来的前几帧是这样的。
如果我给我的代码延迟例如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 && video.loadedmetadata) {
if (delay > DELAY && !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)
}
}
}
使用下面的代码,来自我的 Mac 相机并在 <video>
中显示的视频质量非常好。
然而,我在 p5 canvas 中捕获和显示的帧的质量非常低、暗且有颗粒感。为什么会这样,我可以解决它吗?
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 && 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
}
}
}
你不应该这样设置 width/height。这会弄乱高 DPI 显示器的大小,并导致您的图像显得拉伸和模糊。
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 && 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 canvas 上显示的视频版本与实时视频没有区别。
我找到问题所在了。
不是因为我设置了canvas.elt.width
和canvas.elt.height
,尽管设置它们确实是多余的。
这是因为在 OP 中显示的代码中,我捕获了 第一帧 而这 太快了 所以第一帧框架仍然是黑暗和模糊的。显然从相机传来的前几帧是这样的。
如果我给我的代码延迟例如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 && video.loadedmetadata) {
if (delay > DELAY && !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)
}
}
}