sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.26k stars 1.11k forks source link

Unable to match the human face matrix after setting image rotation and mirroring #923

Closed yang-classmate closed 7 months ago

yang-classmate commented 7 months ago

`package com.tengli.usbcamera.frame;

import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSONObject; import com.arcsoft.face.FaceEngine; import com.arcsoft.face.FaceInfo; import com.arcsoft.face.Rect; import com.arcsoft.face.toolkit.ImageFactory; import com.github.sarxos.webcam.Webcam; import com.github.sarxos.webcam.WebcamImageTransformer; import com.github.sarxos.webcam.WebcamPanel; import com.github.sarxos.webcam.WebcamResolution; import com.github.sarxos.webcam.util.jh.JHFlipFilter; import com.tengli.usbcamera.config.SystemConfig;

import javax.swing.; import java.awt.; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors;

public class FacePainterFrame extends JFrame implements WebcamImageTransformer, WebcamPanel.Painter { private static final long serialVersionUID = 1L; private static final Stroke STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{1.0f}, 0.0f); private static SystemConfig systemConfig = new SystemConfig();

static {
    try {
        final String configPath = System.getProperty("user.dir") + File.separator + "config.conf";
        String configBody = new BufferedReader(new InputStreamReader(new FileInputStream(new File(configPath)))).lines().collect(Collectors.joining("\n"));
        systemConfig = JSONObject.parseObject(configBody, SystemConfig.class);
    } catch (FileNotFoundException e) {
        JOptionPane.showMessageDialog(null, e.getMessage());
    }
}

private final BufferedImageOp filter = new JHFlipFilter(JHFlipFilter.FLIP_90CW);
private final FaceEngine faceEngine;
private WebcamPanel.Painter painter = null;

public FacePainterFrame(FaceEngine faceEngine) {
    super();
    this.faceEngine = faceEngine;
    Dimension[] nonStandardResolutions = new Dimension[]{
            WebcamResolution.XGA.getSize(),
            WebcamResolution.VGA.getSize(),
            new Dimension(systemConfig.getCameraWidth(), systemConfig.getCameraHeight()),
    };
    final Dimension dimension = new Dimension(systemConfig.getCameraWidth(), systemConfig.getCameraHeight());
    Webcam webcam = Webcam.getWebcamByName(systemConfig.getRgbCameraName());
    if (Objects.isNull(webcam)) {
        JOptionPane.showMessageDialog(null, String.format("无法获取到摄像头 %s", systemConfig.getRgbCameraName()));
        System.exit(0);
    }
    WebcamPanel panel = new WebcamPanel(webcam, false);
    try {
        webcam.setCustomViewSizes(nonStandardResolutions);
        webcam.setViewSize(dimension);
        webcam.setImageTransformer(this);//旋转图片
        webcam.open(true);
        panel.setPreferredSize(dimension);
        panel.setPainter(this);
        panel.setMirrored(true);//启用镜像
        panel.setDrawMode(WebcamPanel.DrawMode.FIT);
        panel.start();
        painter = panel.getDefaultPainter();
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e.getMessage());
    }
    add(panel);
    setUndecorated(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
}

@Override
public BufferedImage transform(BufferedImage image) {
    // this will do rotation on image
    return this.filter.filter(image, null);
}

@Override
public void paintPanel(WebcamPanel panel, Graphics2D g2) {
    if (painter != null) {
        painter.paintPanel(panel, g2);
    }
}

@Override
public void paintImage(WebcamPanel panel, BufferedImage image, Graphics2D g2) {
    if (painter != null) {
        painter.paintImage(panel, image, g2);
    }

    System.out.println("g2 width" + g2.getDeviceConfiguration().getBounds().width);
    System.out.println("g2 height" + g2.getDeviceConfiguration().getBounds().height);
    System.out.println("image width" + image.getWidth());
    System.out.println("image height" + image.getHeight());

    List<FaceInfo> faces = new ArrayList<>();
    faceEngine.detectFaces(ImageFactory.bufferedImage2ImageInfo(image), faces);
    if (!CollUtil.isEmpty(faces)) {
        Rect rect = faces.get(0).getRect();
        g2.drawImage(null, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, null);
        g2.setStroke(STROKE);
        g2.setColor(Color.WHITE);
        g2.drawRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
    }

}

}` hi bro,I have encountered a problem.I found that the width and height of Graphics2D and BufferedImage are inconsistent, resulting in a mismatch when drawing the face frame in the end,Do you know what the problem is? Thank you for your answer image

yang-classmate commented 7 months ago

image