您的位置 首页 java

JavaCV 视频图像灰度处理「附代码」

图片灰度处理效果

Java spring boot项目或者maven项目的pom文件中添加以下依赖

 <!--  -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId> javacv -platform</artifactId>
<version>1.5.5</version>
</dependency>  

核心代码,单类实现,idea创建VideoGrayProcessor 类,复制粘贴下面代码,右键点击run运行主方法即可

图像灰度算法

  1. 取得每一个像素的red,green,blue值。
  2. 使用灰度算法,算出一个灰度值。
  3. 用这个灰度值代替像素原始的red,green,blue值。

比如我们的灰度算法是:

 Gray = (Red + Green + Blue) / 3  

主要有图片文字水印和视频水印两个方法,大家可以根据自己的的需求对方法里的参数修改。

 import org.bytedeco. Java cv. FFmpeg FrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
 
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
 
public class VideoGrayProcessor {
 
 
    final static String videoFolderPath = "C:/Users/tarzan/Desktop/video/";
    final static String videoName = "video.mp4";
    final static String imageFolderPath = "C:/Users/tarzan/Desktop/image/";
    final static String imageName = "logo.jpg";
 
 
    public static void main(String[] args) throws Exception {
 
        videoProcess(videoFolderPath + videoName);
 
        imageProcess(imageFolderPath + imageName);
 
    }
 
    //视频水印
    public static void videoProcess(String filePath) {
        //抓取视频图像资源
        FFmpegFrameGrabber videoGrabber = new FFmpegFrameGrabber(filePath);
        //抓取视频图像资源
        FFmpegFrameGrabber audioGrabber = new FFmpegFrameGrabber(filePath);
        try {
            videoGrabber.start();
            audioGrabber.start();
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFolderPath + "new" + videoName, videoGrabber.getImageWidth(), videoGrabber.getImageHeight(), videoGrabber.getAudioChannels());
            recorder.start();
            //处理图像
            int videoSize = videoGrabber.getLengthInVideoFrames();
            for (int i = 0; i < videoSize; i++) {
                Frame videoFrame = videoGrabber.grabImage();
                if (videoFrame != null && videoFrame.image != null) {
                    System.out.println("视频共" + videoSize + "帧,正处理第" + (i + 1) + "帧图片");
                    Java2DFrameConverter converter = new Java2DFrameConverter();
                    BufferedImage bi = converter.getBufferedImage(videoFrame);
                    BufferedImage bufferedImage = grayProcess(bi);
                    recorder.record(converter.convert(bufferedImage));
                }
            }
            //处理音频
            for (int i = 0; i < audioGrabber.getLengthInAudioFrames(); i++) {
                Frame audioFrame = audioGrabber.grabSamples();
                if (audioFrame != null && audioFrame.samples != null) {
                    recorder.recordSamples(audioFrame.sampleRate, audioFrame.audioChannels, audioFrame.samples);
                }
            }
            recorder.stop();
            recorder.release();
            videoGrabber.stop();
            audioGrabber.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    //图片灰度处理
    public static void imageProcess(String sourceFilePath) {
        try {
            BufferedImage image = ImageIO.read(new File(sourceFilePath));
            grayProcess(image);
            String format = sourceFilePath.substring(sourceFilePath.lastIndexOf(".") + 1);
            ImageIO.write(image, format, new File(imageFolderPath + "new" + imageName));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    //灰度处理
    public static BufferedImage grayProcess(BufferedImage bufImg) {
        int width = bufImg.getWidth();
        int height = bufImg.getHeight();
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                bufImg.setRGB(i, j, grayRGB(bufImg.getRGB(i, j)));
            }
        }
        return bufImg;
    }
 
    //rgb灰度转换
    private static int grayRGB(int rgb) {
        int R = (rgb & 0xff0000) >> 16;
        int G = (rgb & 0x00ff00) >> 8;
        int B = rgb & 0x0000ff;
        //平均值
        String average = Integer.toHexString((R + G + B) / 3);
        if (average.length() == 1) {
            average = "0" + average;
        }
        //RGB都变成平均值
        return  Integer .parseInt(average + average + average, 16);
    }
 
 
}  

补充知识:

RGB颜色是由红(Red)、绿(Green)、蓝(Blue)三原色组成的,所以可以使用这三个颜色的组合来代表一种具体的颜色,其中R、G、B的每个数值都位于0-255之间。在表达颜色的时候,即可以使用三个数字来表达,也可以使用一个格式如0X00RRGGBB这样格式的十六进制来表达,下面是常见颜色的表达形式:

  红色:(255,0,0)或0x00FF0000

  绿色:(0,255,0)或0x0000FF00

  蓝色:(0,0,255)或0x00FFFFFF

在编写java图像处理程序时,需要对图像进行灰度化和二值化处理,首先将颜色值与十六进制表示的00ff0000进行“与”运算,运算结果除了表示红色的数字值之外,GGBB部分颜色都为0,在将结果向右移位16位,得到的就是红色值。

同样的,我们也可以通过以下代码得到green和blue的值:

 int red = (rgb & 0x00ff0000) >> 16;
int green = (color & 0x0000ff00) >> 8; // 250 = 0xfa
int blue = (color & 0x000000ff); // 255 = 0xff  

更多图像RGB知识可以百度一下。

控制台运行输出日志

肯动脑筋的小伙伴,把代码稍加改造也可以做成纯黑白画视频。

文章来源:智云一二三科技

文章标题:JavaCV 视频图像灰度处理「附代码」

文章地址:https://www.zhihuclub.com/199988.shtml

关于作者: 智云科技

热门文章

网站地图