java利用opencv实现用字符展示视频或图片

背景:前段时间看到有人将图片转成符号,感觉挺有意思的,就结合了一下opencv。
代码如下:

package org.fxd.utils;

import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * 将图片转成text文件输出
 * @author Litluecat
 */
public class Image2Text {

    static {
        //opencv_java410.dll的所在地址,自己换成自己dll的地址
        System.load("D:\\Sofeware\\opencv\\build\\java\\x64\\opencv_java410.dll");
    }

    /** 此处设置灰度字符*/
    private static char[] cs = new char[] {'0','1','.',' '};

    public static void main(String[] args) throws IOException {
        //String imageUrl = "E:\\1.png";
        // 设置JTextArea,用于展示字符
        JTextArea textArea = getJFrame("XXTop", "宋体", 0, 2, 900, 900);
        // 将图片转成字符
        //textArea.setText(image2Text(imageUrl,1).toString());
        //将视频转成字符
        video2TextByOpenCV(textArea, "E:\\1.mp4", 1);
    }

    /**
     * 生成JFrame窗口,并返回JTextArea对象
     * @param frameTitle 窗口标题
     * @param fontName 文本框中字体类型
     * @param fontStyle 文本框中字体格式
     * @param fontSize 文本框中字体大小
     * @param JFWideth 窗口宽度
     * @param JFHeight 窗口高度
     * @return
     */
    public static JTextArea getJFrame(String frameTitle,String fontName, int fontStyle, int fontSize, int JFWideth, int JFHeight){
        JFrame frame = new JFrame();
        //创建一个窗口对象
        JPanel panel = new JPanel();
        JTextArea textArea = new JTextArea();
        // name:字体类型 style:0,表示字形;1,粗体;2,斜体   size:字体大小
        textArea.setFont(new Font(fontName,fontStyle,fontSize));
        panel.setLayout(new GridLayout());
        //当TextArea里的内容过长时生成滚动条
        panel.add(new JScrollPane(textArea));
        frame.add(panel);
        //对窗口设置标题
        frame.setTitle(frameTitle);
        //设置窗口的大小
        frame.setSize(JFWideth,JFHeight);
        //设置窗口界面的关闭按钮真的生效(也可以直接传一个3进去,JFrame.EXIT_ON_CLOSE==3,效果一样)
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置窗口居中显示
        frame.setLocationRelativeTo(null);
        //设置窗口置顶显示
        frame.setAlwaysOnTop(true);
        //设置窗口显示
        frame.setVisible(true);
        return textArea;
    }

    /**
     * OpenCV-4.1.0 从视频文件中读取
     * @param textArea JTextArea文本框对象
     * @param targetImgUrl 视频地址
     * @param img2TextSzie 图片转文本缩小比例
     */
    public static void video2TextByOpenCV(JTextArea textArea, String targetImgUrl, int img2TextSzie) {
        VideoCapture capture=new VideoCapture();
        //1 读取视频文件的路径
        capture.open(targetImgUrl);
        if(!capture.isOpened()){
            System.out.println("读取视频文件失败!");
            return;
        }
        Mat video=new Mat();
        while(capture.isOpened()) {
            //2 视频文件的视频写入 Mat video 中
            capture.read(video);
            try{
                textArea.setText(image2TextByOpenCV(video,img2TextSzie).toString());
            }catch (Exception e){
                System.out.println("图片识别异常");
                break;
            }
        }
    }

    /**
     *基于openCV实现
     * @param image 待处理Mat图片(视频中的某一帧)
     * @param size 对结果进行缩小,1为不缩小
     */
    public static StringBuffer image2TextByOpenCV(Mat image,int size) throws Exception{
        StringBuffer text = null;
        Mat img_mat = new Mat();
        //mat表示要要转换的图片[Mat类型],img_mat表示转换后的图片
        Imgproc.cvtColor(image, img_mat, Imgproc.COLOR_RGB2GRAY);
        int rows = img_mat.rows();
        int cols = img_mat.cols();
        // 图片转字符串后的数组
        char[][] css = new char[rows/size + 1][cols/size + 1];
        for(int x=0; x<rows; x+=size){
            for (int y=0; y<cols; y+=size){
                //获得图片的灰度值  x,y 表示像素点的位置(姑且理解为像素点吧)
                int gray = (int) img_mat.get(x, y)[0];
                // 得到灰度值
                int index = Math.round((gray * cs.length -1) / 255);
                css[x/size][y/size] = cs[index];
            }
        }
        StringBuffer sb = new StringBuffer();
        // 开始拼接内容
        for (int x = 0; x < css.length; x++) {
            for (int y = 0; y < css[0].length; y++) {
                sb.append(css[x][y]);
            }
            sb.append("\r\n");
        }
        return sb;
    }

    /**
     * @param imageUrl 图片地址
     * @param size 对结果进行缩小,1为不缩小
     */
    public static StringBuffer image2Text(String imageUrl,int size){
        StringBuffer text = null;
        try {
            BufferedImage image = ImageIO.read(new File(imageUrl));
            int width = image.getWidth();
            int height = image.getHeight();
            // 图片转字符串后的数组
            char[][] css = new char[width/size + 1][height/size + 1];
            for (int x = 0; x < width; x+=size) {
                for (int y = 0; y < height; y+=size) {
                    int rgb = image.getRGB(x, y);
                    Color c = new Color(rgb);
                    // 得到灰度值
                    int cc = (c.getRed() + c.getGreen() + c.getBlue()) / 3;
                    css[x/size][y/size] = cs[(int) ((cc * cs.length - 1) / 255)];
                }
            }
            StringBuffer sb = new StringBuffer();
            // 开始拼接内容
            for (int y = 0; y < css[0].length; y++) {
                for (int x = 0; x < css.length; x++) {
                    sb.append(css[x][y]);
                }
                sb.append("\r\n");
            }
            text = sb;
        } catch (IOException e) {
            System.out.println(e);
        }
        return text;
    }

}

效果如下:
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值