如何在JavaFX应用程序中显示OpenCV网络摄像头捕获帧

我正在使用 JavaFX 创建桌面应用程序,该应用程序允许您从网络摄像头扫描二维码。

我决定选择JavaCV来处理网络摄像头翻转。但是,问题是CanvasFrame类创建了一个Swing JFrame。我的主要目标是找到将其与JavaFX组件集成的最佳方法。

我的问题是,是否可以在CanvasFrame(或其他Swing / JavaFx组件)中创建JPanel,而不是在JFrame中创建。在此选项中,我将JPanel包装到SwingNode中-这解决了我的集成问题。

在我的案例中,我还寻求其他解决JavaFX与JavaCV集成问题的建议。 也许有直接的方法可以将相机屏幕嵌入JavaFx组件中。

我要在下面粘贴测试代码。我的代码是用kotlin编写的,但不会影响该问题:

import com.google.zxing.*
import com.google.zxing.client.j2se.BufferedImageLuminanceSource
import com.google.zxing.common.HybridBinarizer
import org.bytedeco.javacv.*
import java.awt.image.BufferedImage
import java.util.*
import java.util.concurrent.Executors

class Test {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            Executors.newSingleThreadExecutor().execute { testWebcam() }
        }

        private fun testWebcam() {
            val grabber: OpenCVFrameGrabber = OpenCVFrameGrabber(0);
            val canvasFrame: CanvasFrame = CanvasFrame("Cam")
            grabber.start()

            while (canvasFrame.isVisible) {
                val frame: Frame = grabber.grabFrame() ?: break
                canvasFrame.showImage(frame)
                decodeQrCode(grabber)
            }
        }

        private fun decodeQrCode(grabber: OpenCVFrameGrabber) {
            val java2DFrameConverter: Java2DFrameConverter = Java2DFrameConverter()

            val frame: Frame = grabber.grabFrame()
            val image = java2DFrameConverter.getBufferedImage(frame)

            val decodedQr = parseQr(image)
            println(decodedQr)
        }

        private fun parseQr(image: BufferedImage): String? {

            val reader: MultiFormatReader = MultiFormatReader()
            val binaryBitmap: BinaryBitmap =
                BinaryBitmap(HybridBinarizer(BufferedImageLuminanceSource(image)))

            val hints: Hashtable<DecodeHintType,Any> = Hashtable()
            hints[DecodeHintType.CHARactER_SET] = "UTF-8"
            hints[DecodeHintType.POSSIBLE_FORMATS] = listOf(BarcodeFormat.QR_CODE)

            return try {
                reader.decode(binaryBitmap,hints).text
            } catch (e: NotFoundException) {
                null;
            }

        }
    }
}
iCMS 回答:如何在JavaFX应用程序中显示OpenCV网络摄像头捕获帧

https://github.com/rladstaetter/javacv-webcam上有一个项目,其中包含将javacv与Swing,JavaFX一起使用的示例,以及在OpenCV和JavaFX的PixelBuffer之间使用共享内存缓冲区的更新方法。

可以使用共享的ByteBuffer支持的JavaFX的ImageView,而不是使用CanvasFrame。伪代码为:

import java.nio.ByteBuffer

import javafx.scene.image._
import org.bytedeco.javacv.Frame
import org.bytedeco.opencv.global.opencv_imgproc._
import org.bytedeco.opencv.opencv_core.Mat

val videoView: ImageView = ImageView()
val grabber: OpenCVFrameGrabber = OpenCVFrameGrabber(0)
grabber.start()

// Fire off a thread to grab frames while the camera is active
// Each frame will ber passed to the updateView method below
// ... timer/thread omitted for brevity

val javaCVMat = Mat()

/** create buffer only once saves much time! */
val buffer: ByteBuffer = javaCVMat.createBuffer()

val formatByte: WritablePixelFormat<ByteBuffer> = PixelFormat.getByteBgraPreInstance()

fun updateView(frame: Frame): Unit = {
  val w = frame.imageWidth()
  val h = frame.imageHeight()

  val mat = javaCVConv.convert(frame)
  cvtColor(mat,javaCVMat,COLOR_BGR2BGRA)

  val pb = PixelBuffer(w,h,buffer,formatByte)
  val wi = WritableImage(pb)
  videoView.setImage(wi)
}

,

我解决了我的问题。就我而言,最好的解决方案是使用.*?

Java2DFrameConverter
本文链接:https://www.f2er.com/1902474.html

大家都在问