看下实现效果
准备工作我们需要导入webcam包
## 视频图像获取:
http://webcam-capture.sarxos.pl/
## 导包:
- Eclipse :
- * 项目:
- 1: 右键项目名 Build Path - Config BuildPath - Lib - add Jars 选中
- IDEA :
- 1:右键项目名 Module Setting
- 2:找到 lib -> +号 Java 选中jar包
实现代码
1videoui类
public class VideoUI extends JFrame {public VideoUI(){setTitle("图像处理");setSize(1000,1000);setDefaultCloseOperation(3);//设置流式布局setLayout(new FlowLayout());VideoListener vl = new VideoListener();addButton (vl);setVisible(true);//摄像头/*只有一个时: */Webcam webcam = Webcam.getDefault();webcam.setViewSize(WebcamResolution.VGA.getSize());webcam.open();PlayVideo playVideo = new PlayVideo();//得将playVIdeo 传到监听器当中去vl.playVideo = playVideo;//这是死循环,之后不能再写代码playVideo.runVideo(webcam,getGraphics());//后面不能加代码}public void addButton(VideoListener vl){// 先定义一个字符串数组 存储所有按钮的字符串String[] btnstrs = {"原图","马赛克","刷新图片", "反片", "脸部提亮", "灰度", "二值化", "美白", "油画", "轮廓提取", "撤回","暖色系","冷色系","珠纹化"};for(int i = 0; i < btnstrs.length; i++){String btnstr = btnstrs[i];JButton btn = new JButton (btnstr);add (btn);// 按钮添加监听器btn.addActionListener (vl);}}public static void main(String[] args) {new VideoUI();}}
2videolistener类
public class VideoListener implements ActionListener {PlayVideo playVideo;@Overridepublic void actionPerformed(ActionEvent e) {String btnstr = e.getActionCommand();//点击按钮之后,修改死循环中的判断所用到的变量的值playVideo.btnstr=btnstr;System.out.println("点击了"+btnstr);}
}
3playvideo类
public class PlayVideo {//定义一个属性 按钮文本String btnstr=""; //得给一个默认值,不然提示报错为空;
//VideoEff 视频效果对象imageEff VideoEff imageEff = new VideoEff();/**播放视频*/public void runVideo(Webcam webcam, Graphics g){//用死循环来一帧一帧处理图片while (true){//1、获取图片BufferedImage img = webcam.getImage();int [][]imagePixArray = imageEff.getImagePixArray(img);//2、判断如何处理图片if(btnstr.equals("原图")){//不需要处理g.drawImage(img,100,100,null);}if(btnstr.equals("马赛克")){//传入图像数组,图片对象,视频效果对象调用该类中的方法来绘制imageEff.drawImage_02(imagePixArray,g);}if(btnstr.equals ("反片")){imageEff.drawImage_03(imagePixArray,g);}if(btnstr.equals ("脸部提亮")){imageEff.drawImage_04(imagePixArray,g);}if(btnstr.equals ("灰度")){imageEff.drawImage_05(imagePixArray,g);}if(btnstr.equals ("二值化")){imageEff.drawImage_06(imagePixArray,g);}if(btnstr.equals ("油画")){imageEff.drawImage_08(imagePixArray,g);}if(btnstr.equals ("轮廓提取")){imageEff.drawImage_09(imagePixArray,g);}if(btnstr.equals("珠纹化")) {imageEff.drawImage_13(imagePixArray,g);}}}
}
4videoeff类
public class VideoEff {//图片绘制坐标的参数final int X=100;final int Y=100;/*** 将一张图片转为二位数** @param buffimg* 缓冲图片对象* @return 存有图片像素值的二维数组*/public int[][] getImagePixArray(BufferedImage buffimg) {// 获取图片尺寸int w=buffimg.getWidth();int h=buffimg.getHeight();//创建新的二维数组来保存图片信息int [][]imgarr=new int[w][h];for(int i=0;i<w;i++) {for(int j=0;j<h;j++) {imgarr[i][j]=buffimg.getRGB(i,j);}}//返回图片数组return imgarr;}//————————————————————————————————————————————————————————————————————————————————————//以下是绘制图片效果部分/*** 1、绘制原图方法* @param imgarr 图片数组* @param g 图像画笔对象*/public BufferedImage drawImage_01(int[][] imgarr,Graphics g) {BufferedImage img = new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);// 如何不绘制特殊形状, 可以考虑直接设置RGBfor(int i=0;i<imgarr.length;i++) {for(int j=0;j<imgarr[i].length;j++) {int rgb = imgarr[i][j];//将RGB 遍历存入BufferedImage;img.setRGB(i,j,rgb);}}g.drawImage(img,X,Y,null);return img;}* 2、马赛克:每隔几个点取几个像素,并将图像放大 只需要在原图基础上设置取点位置以及放大g的宽和高* @param imgarr 图片数组* @param g 图像画笔对象*/public BufferedImage drawImage_02(int[][] imgarr,Graphics g) {BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);//获取缓冲区画
// g = img.getGraphics();for(int i=0;i<imgarr.length;i+=10) {for(int j=0;j<imgarr[i].length;j+=10) {int rgb = imgarr[i][j];Color color =new Color(rgb);g.setColor(color);g.fillRect(X+i,Y+j,10,10);}}g.drawImage(img,X,Y,null);return img;}/*** 3、反片 利用获取颜色255-red,255-green,255-blue来做处理* @param imgarr 图片数组* @param g 图像画笔对象*/public BufferedImage drawImage_03(int[][] imgarr,Graphics g) {//创建缓冲图片BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);// Graphics g1 = img.getGraphics();for(int i=0;i<imgarr.length;i++) {for(int j=0;j<imgarr[i].length;j++) {int rgb = imgarr[i][j];Color color =new Color(rgb);int red = color.getRed();int blue = color.getBlue();int green = color.getGreen();Color ncolor =new Color(255-red,255-green,255-blue);g.setColor(ncolor);g.fillRect(X+i,Y+j,1,1);}}g.drawImage(img,X,Y,null);return img;}/*** 4、脸部提亮* @param imgarr 图片数组* @param g 图像画笔对象* @return*/public BufferedImage drawImage_04(int[][] imgarr,Graphics g) {BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);for(int i=0;i<imgarr.length;i++) {for(int j=0;j<imgarr[i].length;j++) {int rgb = imgarr[i][j];Color color =new Color(rgb);int red = color.getRed();int blue = color.getBlue();int green = color.getGreen();int grey = (int)(red*0.299+green*0.587+blue*0.114);Color ncolor = new Color(Math.abs(red-255+245),green,blue);g.setColor(ncolor);g.fillRect(X+i,Y+j,1,1);}}g.drawImage(img,X,Y,null);return img;}/*** 5、灰度处理* @param imgarr 图片数组* @param g 图像画笔对象* @return*/public BufferedImage drawImage_05(int[][] imgarr,Graphics g) {//创建缓冲图片BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);//获取缓冲区笔for(int i=0;i<imgarr.length;i++) {for(int j=0;j<imgarr[i].length;j++) {int rgb = imgarr[i][j];Color color =new Color(rgb);int red = color.getRed();int blue = color.getBlue();int green = color.getGreen();//int grey = (int)(red+blue+green)/3; 较为简单的方法
// RGB转换成灰度图像的方法
// Gray = R*0.299 + G*0.587 + B*0.114//更精确的表示int grey = (int)(red*0.299+green*0.587+blue*0.114);Color ncolor = new Color(grey,grey,grey);g.setColor(ncolor);g.fillRect(X+i,Y+j,1,1);}}g.drawImage(img,X,Y,null);return img;}/*** 6、二值化* @param imgarr 图片数组* @param g 图像画笔对象* @return*/public BufferedImage drawImage_06(int[][] imgarr,Graphics g) {BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);for(int i=0;i<imgarr.length;i++) {for(int j=0;j<imgarr[i].length;j++) {int rgb = imgarr[i][j];Color color =new Color(rgb);int red = color.getRed();int blue = color.getBlue();int green = color.getGreen();//先进行灰度化处理int grey = (int)(red*0.299+green*0.587+blue*0.114);Color ncolor = new Color(grey,grey,grey);
//用灰度值大小与110进行比较(修改参数值可以得到不同的深浅度)if(grey <110){g.setColor (Color.BLACK);}else{g.setColor (Color.WHITE);}g.fillRect (100 + i, 100 + j, 1, 1);}}g.drawImage(img,X,Y,null);return img;}/*** 8、油画* @param imgarr 图片数组* 原理:每隔五个像素点取一个,然后用随机大小的椭圆填充每个像素点周围的区域* @param g 图像画笔对象* return*/public BufferedImage drawImage_08(int[][] imgarr,Graphics g) {BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);for(int i=0;i<imgarr.length-5;i+=5) {for(int j=0;j<imgarr[i].length-5;j+=5) {int rgb = imgarr[i][j];Color color =new Color(rgb);g.setColor(color);Random ran=new Random();int r=ran.nextInt(20)+5;g.fillOval(X+i,Y+j,r,r);}}g.drawImage(img,X,Y,null);return img;}/*** 9、轮廓处理* @param imgarr 图片数组* @param g 图像画笔对象* @return*/public BufferedImage drawImage_09(int[][] imgarr, Graphics g){BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);for(int i = 0; i < imgarr.length-1; i++){for(int j = 0; j < imgarr[i].length-1; j++){int rgb = imgarr[i][j];Color color = new Color (rgb);int red = color.getRed ();int green = color.getGreen ();int blue = color.getBlue ();int gray = (int) (red * 0.41 + green * 0.36 + blue * 0.23);// 取出右下斜方向的像素按照 灰度值 作比较int nrgb = imgarr[i + 1][j + 1];Color ncolor = new Color (nrgb);int nred = ncolor.getRed ();int ngreen = ncolor.getGreen ();int nblue = ncolor.getBlue ();int ngray = (int) (nred * 0.41 + ngreen * 0.36 + nblue * 0.23);if(Math.abs (gray - ngray) > 15){g.setColor (Color.black);} else{g.setColor (Color.white);}g.fillRect (X + i, Y + j, 1, 1);}}g.drawImage(img,X,Y,null);return img;}/*** 13、珠纹化* @param imgarr 图片数组* @param g 图像画笔对象* 原理,每隔10取一个像素点,后用大小为9的圆填充*/public BufferedImage drawImage_13(int[][] imgarr,Graphics g) {BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);for(int i=0;i<imgarr.length;i+=10) {for(int j=0;j<imgarr[i].length;j+=10) {int rgb = imgarr[i][j];Color color =new Color(rgb);g.setColor(color);g.fillOval(X+i,Y+j,9,9);}}g.drawImage(img,X,Y,null);return img;}