news 2026/7/6 4:19:34

双摄像头实时预览与图像处理系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双摄像头实时预览与图像处理系统

多线程相关知识点

  • 进程与线程的概念:
    • 进程:进行中的程序,任何一个进程至少有一个线程
      • 进程是操作系统分配资源的最小单位
    • 线程:进程中的一个子分支,可以独立运行
      • CPU执行的最小单位
    • 物理线程:CPU的逻辑处理器数,CPU在绝对的同时只能执行这个数量的线程
    • 线程开关控制:
      • 开:需要有新的线程对象创建并启动
      • 关:一个线程结束执行的唯一标准是run方法中的代码执行完毕

Cam1Show

  • 打开摄像头1
  • 灰度马赛克滤镜处理
  • 绘制到窗口
import com.github.sarxos.webcam.Webcam; import java.awt.*; import java.awt.image.BufferedImage; public class Cam1Show extends Thread{ Webcam cam;//摄像头对象 Graphics g; public void run(){//线程启动后执行的代码 //1.设置摄像头分辨率 cam.setViewSize(new Dimension(640,480)); //2.打开摄像头 cam.open(); System.out.println("相机1打开"); //3.无限循环,不断读取画面并处理 while (true){ if(!cam.isOpen()){ break; } //4.获取一帧画面 BufferedImage image=cam.getImage(); //5.灰度马赛克处理 for (int i = 0; i < image.getWidth()-10; i+=10) { for (int j = 0; j < image.getHeight()-10; j+=10) { //获取采样点颜色 int rgb=image.getRGB(i,j); Color c1=new Color(rgb); int red=c1.getRed(); int green=c1.getGreen(); int blue=c1.getBlue(); //计算灰度值 int gray=(red+green+blue)/3; Color c2=new Color(gray,gray,gray); //将10x10区域全部转化为灰色 for(int k=0;k<10;k++){ for (int l = 0; l < 10; l++) { image.setRGB(i+k,j+l,c2.getRGB()); } } } } //6.将处理后的画面绘制到窗口上 g.drawImage(image,80,100,null); } System.out.println("相机1关闭"); System.out.println(this.getState());//打印线程状态 } }

Cam2Show

  • 打开摄像头2
  • 直接显示原始画面
  • 绘制到窗口
import java.awt.*; import java.awt.image.BufferedImage; public class Cam2Show extends Thread{ Webcam cam; Graphics g; public void run(){ cam.setViewSize(new Dimension(640,480)); cam.open(); System.out.println("相机2打开"); while(true){ if(!cam.isOpen()){ break; } BufferedImage image=cam.getImage(); g.drawImage(image,750,100,null); } System.out.println("相机2关闭"); System.out.println(this.getState()); } }

CamListener

  • 响应按钮点击
  • 开启/关闭对应摄像头线程
import com.github.sarxos.webcam.Webcam; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class CamListener implements ActionListener{ Webcam cam1; Webcam cam2; Cam1Show cam1Show;//摄像头1的线程对象 Cam2Show cam2Show;//摄像头2的线程对象 JFrame jf; @Override public void actionPerformed(ActionEvent e) { String ac=e.getActionCommand();//获取按钮文字 JButton btn=(JButton) e.getSource();//获取被点击的按钮 if(ac.equals("相机1开启")){ btn.setText("相机1关闭"); cam1Show=new Cam1Show(); cam1Show.g=jf.getGraphics(); cam1Show.cam=cam1; cam1Show.start();//启动线程 }else if(ac.equals("相机1关闭")){ btn.setText("相机1开启"); cam1.close(); cam1Show.interrupt(); } else if (ac.equals("相机2开启")) { btn.setText("相机2关闭"); cam2Show=new Cam2Show(); cam2Show.g=jf.getGraphics(); cam2Show.cam=cam2; cam2Show.start(); } else if (ac.equals("相机2关闭")) { btn.setText("相机2开启"); cam2.close(); cam2Show.interrupt(); } } }

Test1类

  • 获取摄像头列表
  • 创建窗口
  • 创建两个按钮(控制摄像头开启/关闭)
  • 创建两个显示线程
  • 连接按钮与监听器
import com.github.sarxos.webcam.Webcam; import javax.swing.*; import java.awt.*; import java.util.List; public class Test1 { static void main() { //1.获取电脑上所有摄像头 List<Webcam> webcamList=Webcam.getWebcams(); for (int i = 0; i < webcamList.size(); i++) { System.out.println(webcamList.get(i).getName()); } Webcam cam1=webcamList.get(0);//第一个摄像头 Webcam cam2=webcamList.get(2);//第三个摄像头 //2.创建窗口 JFrame jf=new JFrame(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setSize(1500,900); jf.setLocationRelativeTo(null); jf.setLayout(null); //3.创建两个按钮 JButton btn1=new JButton("相机1开启"); JButton btn2=new JButton("相机2开启"); btn1.setBounds(300,600,100,50); btn2.setBounds(800,800,100,50); jf.add(btn1); jf.add(btn2); jf.setVisible(true); //4.创建两个显示线程对象 Cam1Show cam1Show=new Cam1Show(); Cam2Show cam2Show=new Cam2Show(); //5.获取画笔 Graphics g=jf.getGraphics(); cam1Show.g=g; cam2Show.g=g; cam1Show.cam=cam1; cam2Show.cam=cam2; //6.创建监听器并连接按钮 CamListener cam3=new CamListener(); cam3.cam1=cam1; cam3.cam1Show=cam1Show; cam3.jf=jf; btn1.addActionListener(cam3); CamListener cam4=new CamListener(); cam4.cam2=cam2; cam4.cam2Show=cam2Show; cam4.jf=jf; btn2.addActionListener(cam4); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 4:18:37

Linux上运行Windows软件的终极解决方案:Bottles完整指南

Linux上运行Windows软件的终极解决方案&#xff1a;Bottles完整指南 【免费下载链接】Bottles Run Windows software and games on Linux 项目地址: https://gitcode.com/gh_mirrors/bo/Bottles 还在为Linux系统无法运行Windows专属软件而苦恼吗&#xff1f;&#x1f91…

作者头像 李华
网站建设 2026/7/6 4:16:59

MAVProxy架构解析:模块化无人机地面站的技术实现

MAVProxy架构解析&#xff1a;模块化无人机地面站的技术实现 【免费下载链接】MAVProxy MAVLink proxy and command line ground station 项目地址: https://gitcode.com/gh_mirrors/ma/MAVProxy MAVProxy作为基于Python的开源MAVLink代理和地面站系统&#xff0c;采用高…

作者头像 李华
网站建设 2026/7/6 4:15:44

数据视图笔记

一、创建&#xff08;1&#xff09;普通数据表创建 创建数据表需要一步步规划字段名、数据类型&#xff0c;还要配置主键、非空、外键等各类约束&#xff0c;建好之后表会占用物理磁盘空间存储真实数据&#xff0c;后续改动表结构比较繁琐。 代码示例&#xff1a; CREATE TABLE…

作者头像 李华
网站建设 2026/7/6 4:14:33

LED闪烁/LED流水灯/蜂鸣器

高电平弱驱动&#xff0c;低电平的强驱动 操作stm32的GPIO口&#xff1a;1.使用RCC开启GPIO时钟2.GPIO.Init函数初始化GPIO3.使用输入输出函数控RCC 库函数void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32…

作者头像 李华
网站建设 2026/7/6 4:12:46

SPI、UART和I2C通信协议

SPISPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写。SPI是一种串行、全双工、同步的通信总线&#xff0c;支持主从模式。通信逻辑线&#xff1a;MISO&#xff1a;Master input slave output 主机输入&#xff0c;从机输出&#xff08;数据来自从…

作者头像 李华
网站建设 2026/7/6 4:11:18

三甲医院系统“裸奔”?我用腾讯AI搭子,憋出了个标杆级权限方案!

最近&#xff0c;我接到了一个让人后背发凉的“烫手山芋”。 一家三甲医院的客户找到我&#xff0c;说他们底层操作系统的权限开放得实在太大了&#xff0c;简直处于“裸奔”边缘。他们希望我能帮忙设计一套基于堡垒机和操作系统层面的权限规范管理方案。 需求很明确&#xf…

作者头像 李华