1. 程式人生 > 程式設計 >Java利用opencv實現用字元展示視訊或圖片的方法

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","宋體",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;
  }

}

效果如下:

在這裡插入圖片描述

到此這篇關於Java利用opencv實現用字元展示視訊或圖片的方法的文章就介紹到這了,更多相關java實現展示視訊或圖片內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!