功能說明:希望在現有JFrame的右下角實作一個攝像頭實時視訊的小視窗,記錄一下實作的過程。
1、javaCV環境配置
這裡不再贅述了,可以參考 https://blog.csdn.net/liyuqian199695/article/details/53925478
注:jar包導入時要比對電腦的系統版本。
下面是測試代碼
import javax.swing.JFrame;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.FrameGrabber.Exception;
import org.bytedeco.javacv.OpenCVFrameGrabber;
public class JavacvCameraTest
{
public static void main(String[] args) throws Exception, InterruptedException
{
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start(); //開始擷取攝像頭資料
CanvasFrame canvas = new CanvasFrame("Camera");//建立一個視窗
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.setAlwaysOnTop(true);
while(true)
{
if(!canvas.isDisplayable())
{//視窗是否關閉
grabber.stop();//停止抓取
grabber.close();
System.exit(2);//退出
}
canvas.showImage(grabber.grab());//擷取攝像頭圖像并放到視窗上顯示, 這裡的Frame frame=grabber.grab(); frame是一幀視訊圖像
Thread.sleep(10);//10毫秒重新整理一次圖像
}
}
}
2、攝像頭小視窗加到JFrame
問題:grabber.grab()擷取的圖像格式是Frame,Frame之間是可以切換顯示的。但是,其中一個不能加到另一種中進行顯示(百度了好久也不能)。
解決思路:将grabber.grab()轉為圖檔格式,然後在控件中顯示圖檔。
grabber.grab()-->IplImage-->BufferedImage
如下是IplImage-->BufferedImage
public static BufferedImage iplToBufImgData(IplImage mat) {
if (mat.height() > 0 && mat.width() > 0) {
BufferedImage image = new BufferedImage(mat.width(), mat.height(),
BufferedImage.TYPE_3BYTE_BGR);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
mat.getByteBuffer().get(data);
BytePointer bytePointer =new BytePointer(data);
mat.imageData(bytePointer);
return image;
}
return null;
}
3、圖檔尺寸變化
實時視訊的小視窗顯示需要改變圖檔的大小。
ImageIcon image = new ImageIcon(bi);
image.setImage(image.getImage().getScaledInstance(470, 270,Image.SCALE_DEFAULT ));
GUIVideo.label.setIcon(image);//轉換圖像格式并輸出
注:bi是BufferedImage的類對象。