Java使用OpenCV进行答题卡识别

2022-09-09 08:55:50 浏览数 (1)

前言

安装OpenCV

Windows环境

https://github.com/opencv/opencv/releases

下载这个

下面的exe也可以 这个exe是一个自解压文件

安装的时候选择目录的时候不用新建opencv,在解压的时候会自动创建opencv文件夹。

CentOS源码编译

下载到服务器上

安装依赖

代码语言:javascript复制
yum groupinstall -y "Development Tools"

sudo yum -y install epel-release cmake3 gtk2-devel libpng-devel jasper-devel openexr-devel libwebp-devel libjpeg-turbo-devel libtiff-devel tbb-devel eigen3-devel boost boost-thread boost-devel libv4l-devel

查看gcc版本

代码语言:javascript复制
gcc -v

安装:

代码语言:javascript复制
unzip opencv-4.6.0.zip
cd opencv-4.6.0 && mkdir build && cd build

cmake3 -D CMAKE_BUILD_TYPE=RELEASE 
  -D CMAKE_INSTALL_PREFIX=/usr/local/opencv4 
  -D OPENCV_GENERATE_PKGCONFIG=ON ..

然后输入下述命令进行编译:

代码语言:javascript复制
make -j8

使用make -j4或者make -j8进行多线程编译,虽然速度快但是容易出问题。

使用make如果中间如果因为特殊原因断了,可以使用make命令再继续。

编译100%完成后最后输入下述命令进行安装:

代码语言:javascript复制
make install

输入以下命令:

代码语言:javascript复制
cd /etc/ld.so.conf.d/
sudo touch opencv.conf
sudo sh -c 'echo "/usr/local/opencv4/lib64" > opencv.conf' 
sudo ldconfig

然后,复制.pc文件:

代码语言:javascript复制
sudo cp -f /usr/local/opencv4/lib64/pkgconfig/opencv4.pc /usr/lib64/pkgconfig/opencv4.pc

注意,我安装的是4.6.0,生成的是opencv4.pc,不是opencv.pc 测试一下:

代码语言:javascript复制
pkg-config --modversion opencv4

升级cmake

注意

本文中使用的cmake3就不用再升级cmake了。

cmake需要3.5.1以上的版本

代码语言:javascript复制
sudo yum install build-essential libssl-dev
wget http://www.cmake.org/files/v3.16/cmake-3.16.6.tar.gz
tar xf cmake-3.16.6.tar.gz
sudo chmod -R 777 cmake-3.16.6
cd cmake-3.16.6
./bootstrap
make
make install

通过yum命令移除原先的CMake。

代码语言:javascript复制
yum remove cmake -y

建立目标版本CMake的软连接。

代码语言:javascript复制
ln -s /usr/local/bin/cmake /usr/bin

查看版本

代码语言:javascript复制
cmake --version

升级libstdc

升级cmake的时候又报错

version `GLIBCXX_3.4.20‘ not found 解决方法

解决方法

代码语言:javascript复制
su root
cd /usr/local/lib64
# 下载最新版本的libstdc.so_.6.0.26
sudo wget http://www.vuln.cn/wp-content/uploads/2019/08/libstdc.so_.6.0.26.zip
unzip libstdc.so_.6.0.26.zip
# 将下载的最新版本拷贝到 /usr/lib64
cp libstdc  .so.6.0.26 /usr/lib64
cd  /usr/lib64
# 查看 /usr/lib64下libstdc  .so.6链接的版本
ls -l | grep libstdc  

可以看到

libstdc .so.6 ->libstdc .so.6.0.19

代码语言:javascript复制
# 删除/usr/lib64原来的软连接libstdc  .so.6,删除之前先备份一份
sudo rm libstdc  .so.6
# 链接新的版本
sudo ln -s libstdc  .so.6.0.26 libstdc  .so.6
# 查看新版本,成功
strings /usr/lib64/libstdc  .so.6 | grep GLIBCXX

CentOS中YUM安装

代码语言:javascript复制
yum install opencv opencv-devel opencv-python -y
pkg-config --modversion opencv

卸载

代码语言:javascript复制
yum remove opencv opencv-devel opencv-python -y

Ubuntu中APT安装

代码语言:javascript复制
sudo apt update
sudo apt install -y libopencv-dev python3-opencv

获取版本

代码语言:javascript复制
python3 -c "import cv2; print(cv2.__version__)"

卸载

代码语言:javascript复制
sudo apt remove -y libopencv-dev python3-opencv

Ubuntu源码编译

https://github.com/opencv/opencv/releases

添加环境依赖

代码语言:javascript复制
sudo apt install -y build-essential cmake git pkg-config libgtk-3-dev 
    libavcodec-dev libavformat-dev libswscale-dev libv4l-dev 
    libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev 
    gfortran openexr libatlas-base-dev python3-dev python3-numpy 
    libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev 
    libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev

cmake需要3.5.1以上的版本

查看cmake版本

代码语言:javascript复制
cmake --version

安装:

代码语言:javascript复制
unzip opencv-4.6.0.zip
cd opencv-4.6.0
mkdir build && cd build

cmake -D CMAKE_BUILD_TYPE=RELEASE 
  -D CMAKE_INSTALL_PREFIX=/usr/local/opencv4 
  -D OPENCV_GENERATE_PKGCONFIG=ON ..

然后输入下述命令进行编译:

代码语言:javascript复制
make -j12

使用make -j4或者make -j8进行多线程编译,虽然速度快但是容易出问题。

使用make如果中间如果因为特殊原因断了,可以使用make命令再继续。

编译100%完成后最后输入下述命令进行安装:

代码语言:javascript复制
make install

输入以下命令:

代码语言:javascript复制
cd /etc/ld.so.conf.d/
sudo touch opencv.conf
# 根据安装位置
sudo sh -c 'echo "/usr/local/opencv4/lib" > opencv.conf' 
sudo ldconfig

然后,复制.pc文件:

代码语言:javascript复制
sudo cp -f /usr/local/opencv4/lib/pkgconfig/opencv4.pc /usr/lib/pkgconfig/opencv4.pc

注意,我安装的是4.6.0,生成的是opencv4.pc,不是opencv.pc 测试一下:

代码语言:javascript复制
pkg-config --modversion opencv4

加载依赖

项目中添加jar

jar的位置在安装目录下buildjava的目录下。

下面两种方式任选其一即可。

推荐方式1,方式2在Linux上就失效了。

方式1

添加测试代码

代码语言:javascript复制
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;

public class Test01 {
  static {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  }

  public static void main(String[] args) {
    System.out.println("Welcome to OpenCV "   Core.VERSION);
    Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
    System.out.println("OpenCV Mat: "   m);
    Mat mr1 = m.row(1);
    mr1.setTo(new Scalar(1));
    Mat mc5 = m.col(5);
    mc5.setTo(new Scalar(5));
    System.out.println("OpenCV Mat data:n"   m.dump());
  }
}

配置运行时参数。

通过菜单Run->Edit Configurations...打开Run/Debug Configurations对话框。

在对话框窗口右侧,找到VM options标签对应的文本框。

在文本框中填写参数

-Djava.library.path=D:Toolsopencvbuildjavax64

看好自己电脑是64为就选x64,32位就选x86。

当然也可以直接把opencv_java455.dll放在Java的bin目录下,这样也就不用配置java.library.path

D:ToolsJavajdk1.8.0_102bin

方式2

这种方式就不用再指定java.library.path了。

把jar和dll放到项目中。

代码中

代码语言:javascript复制
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import java.net.URL;

public class Test01 {
  static {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java455.dll");
    System.load(url.getPath());
  }

  public static void main(String[] args) {
    System.out.println("Welcome to OpenCV "   Core.VERSION);
    Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
    System.out.println("OpenCV Mat: "   m);
    Mat mr1 = m.row(1);
    mr1.setTo(new Scalar(1));
    Mat mc5 = m.col(5);
    mc5.setTo(new Scalar(5));
    System.out.println("OpenCV Mat data:n"   m.dump());
  }
}

常用方法

代码语言:javascript复制
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import utils.OpenCVUtil;


public class Test01 {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static void main(String[] args) {
        // 以灰度方式,读取图片
        Mat img = Imgcodecs.imread("D:\Pic\0.png", Imgcodecs.IMREAD_GRAYSCALE);
        Imgcodecs.imwrite("D:\Pic\1.png", img);
        
        // 转成二值化图片
        Mat img2 = new Mat();
        Imgproc.threshold(img, img2, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
        Imgcodecs.imwrite("D:\Pic\2.png", img2);
        
        // 膨胀
        Mat img3 = OpenCVUtil.eroding(img2);
        Imgcodecs.imwrite("D:\Pic\3.png", img3);


    }
}

如上就分别展示了

  1. 图片转灰度
  2. 灰度图片二值化
  3. 二值化图片黑色区域膨胀
  4. 图片的裁剪

灰度

代码语言:javascript复制
// 以灰度方式,读取图片
Mat img = Imgcodecs.imread("D:\Pic\0.png", Imgcodecs.IMREAD_GRAYSCALE);
Imgcodecs.imwrite("D:\Pic\1.png", img);

二值化

代码语言:javascript复制
// 转成二值化图片
Mat img2 = new Mat();
Imgproc.threshold(img, img2, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
Imgcodecs.imwrite("D:\Pic\2.png", img2);

膨胀

代码语言:javascript复制
// 膨胀
Mat img3 = OpenCVUtil.eroding(img2);
Imgcodecs.imwrite("D:\Pic\3.png", img3);

高斯模糊

代码语言:javascript复制
Mat img01 = new Mat();
Imgproc.GaussianBlur(img, img01, new Size(1, 1), 10, 10);
Imgcodecs.imwrite("D:\Pic\img01.png", img01);

剪裁

代码语言:javascript复制
// 截取左上角四分之一区域
Rect rect = new Rect(0, 0, img2.cols() / 2, img2.rows() / 2);
Mat img4 = new Mat(img2, rect);
Imgcodecs.imwrite("D:\Pic\4.png", img4);

工具类

通用

代码语言:javascript复制
package utils.opencv;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import java.util.*;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class OpenCVUtil {
  public static BufferedImage covertMat2Buffer(Mat mat) throws IOException {
    long time1 = new Date().getTime();
    // Mat 转byte数组
    BufferedImage originalB = toBufferedImage(mat);
    long time3 = new Date().getTime();
    System.out.println("保存读取方法2转="   (time3 - time1));
    return originalB;
    // ImageIO.write(originalB, "jpg", new File("D:\test\testImge\ws2.jpg"));
  }

  public static byte[] covertMat2Byte(Mat mat) throws IOException {
    long time1 = new Date().getTime();
    // Mat 转byte数组
    byte[] return_buff = new byte[(int) (mat.total() * mat.channels())];
    Mat mat1 = new Mat();
    mat1.get(0, 0, return_buff);
    long time3 = new Date().getTime();
    System.out.println(mat.total() * mat.channels());
    System.out.println("保存读取方法2转="   (time3 - time1));
    return return_buff;
  }

  public static byte[] covertMat2Byte1(Mat mat) throws IOException {
    long time1 = new Date().getTime();
    MatOfByte mob = new MatOfByte();

    Imgcodecs.imencode(".jpg", mat, mob);

    long time3 = new Date().getTime();
    // System.out.println(mat.total() * mat.channels());
    System.out.println("Mat转byte[] 耗时="   (time3 - time1));
    return mob.toArray();
  }

  public static BufferedImage toBufferedImage(Mat m) {
    int type = BufferedImage.TYPE_BYTE_GRAY;
    if (m.channels() > 1) {
      type = BufferedImage.TYPE_3BYTE_BGR;
    }
    int bufferSize = m.channels() * m.cols() * m.rows();
    byte[] b = new byte[bufferSize];
    m.get(0, 0, b); // get all the pixels
    BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
    final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    System.arraycopy(b, 0, targetPixels, 0, b.length);
    return image;
  }

  /**
     * 腐蚀膨胀是针对于白色区域来说的,腐蚀即腐蚀白色区域
     * 腐蚀算法(黑色区域变大)
     *
     * @param source
     * @return
     */
  public static Mat eroding(Mat source) {
    return eroding(source, 1);
  }

  public static Mat eroding(Mat source, double erosion_size) {
    Mat resultMat = new Mat(source.rows(), source.cols(), source.type());
    Mat element = Imgproc.getStructuringElement(
      Imgproc.MORPH_RECT,
      new Size(erosion_size   1, erosion_size   1)
    );
    Imgproc.erode(source, resultMat, element);
    return resultMat;
  }

  /**
     * 腐蚀膨胀是针对于白色区域来说的,膨胀是膨胀白色区域
     * 膨胀算法(白色区域变大)
     *
     * @param source
     * @return
     */
  public static Mat dilation(Mat source) {
    return dilation(source, 1);
  }

  /**
     * 腐蚀膨胀是针对于白色区域来说的,膨胀是膨胀白色区域
     *
     * @param source
     * @param dilation_size 膨胀因子2*x 1 里的x
     * @return Mat
     */
  public static Mat dilation(Mat source, double dilation_size) {
    Mat resultMat = new Mat(source.rows(), source.cols(), source.type());
    Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(2 * dilation_size   1,
                                                                             2 * dilation_size   1));
    Imgproc.dilate(source, resultMat, element);
    return resultMat;
  }
}

透视变换

代码语言:javascript复制
package utils.opencv;

import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.utils.Converters;

import java.util.Arrays;
import java.util.List;

/**
 * 透视变换工具类
 * 因为我透视变换做的也不是很好,就仅提供一个大概的函数...
 */
public class WarpPerspectiveUtils {

  /**
     * 透视变换
     *
     * @param src
     * @param points
     * @return
     */
  public static Mat warpPerspective(Mat src, Point[] points) {
    // 点的顺序[左上 ,右上 ,右下 ,左下]
    List<Point> listSrcs = Arrays.asList(
      points[0],
      points[1],
      points[2],
      points[3]
    );
    Mat srcPoints = Converters.vector_Point_to_Mat(listSrcs, CvType.CV_32F);

    List<Point> listDsts = Arrays.asList(
      new Point(0, 0),
      new Point(src.width(), 0),
      new Point(src.width(), src.height()),
      new Point(0, src.height())
    );


    Mat dstPoints = Converters.vector_Point_to_Mat(listDsts, CvType.CV_32F);

    Mat perspectiveMmat = Imgproc.getPerspectiveTransform(dstPoints, srcPoints);

    Mat dst = new Mat();

    Imgproc.warpPerspective(
      src,
      dst,
      perspectiveMmat,
      src.size(),
      Imgproc.INTER_LINEAR   Imgproc.WARP_INVERSE_MAP,
      1,
      new Scalar(0)
    );

    return dst;
  }
}

轮廓相关

代码语言:javascript复制
package utils.opencv;

import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;

import java.util.Vector;

/**
 * 轮廓工具类
 */
public class ContoursUtils {

  /**
     * 获取图片的四个顶点
     *
     * @param img
     * @return
     */
  public static Point[] getAllPoints(Mat img) {
    Point[] potArr = new Point[4];
    for (int i = 0; i < 4; i  ) {
      potArr[i] = new Point(-1, -1);
    }

    int[] spaceArr = new int[]{-1, -1, -1, -1};
    int cols = img.cols();
    int rows = img.rows();
    int x1 = cols / 3;
    int x2 = cols * 2 / 3;
    int y1 = rows / 3;
    int y2 = rows * 2 / 3;
    for (int x = 0; x < cols; x  ) {
      for (int y = 0; y < rows; y  ) {
        if (x > x1 && x < x2 && y > y1 && y < y2) {
          continue;
        }
        double[] darr = img.get(y, x);
        if (darr != null && darr.length >= 1 && darr[0] == 0) {
          if (spaceArr[0] == -1) {
            potArr[0].x = x;
            potArr[0].y = y;
            potArr[1].x = x;
            potArr[1].y = y;
            potArr[2].x = x;
            potArr[2].y = y;
            potArr[3].x = x;
            potArr[3].y = y;
            spaceArr[0] = getSpace(0, 0, x, y);
            spaceArr[1] = getSpace(cols, 0, x, y);
            spaceArr[2] = getSpace(cols, rows, x, y);
            spaceArr[3] = getSpace(0, rows, x, y);
          } else {
            int s0 = getSpace(0, 0, x, y);
            int s1 = getSpace(cols, 0, x, y);
            int s2 = getSpace(cols, rows, x, y);
            int s3 = getSpace(0, rows, x, y);
            if (s0 < spaceArr[0]) {
              spaceArr[0] = s0;
              potArr[0].x = x;
              potArr[0].y = y;
            }
            if (s1 < spaceArr[1]) {
              spaceArr[1] = s1;
              potArr[1].x = x;
              potArr[1].y = y;
            }
            if (s2 < spaceArr[2]) {
              spaceArr[2] = s2;
              potArr[2].x = x;
              potArr[2].y = y;
            }
            if (s3 < spaceArr[3]) {
              spaceArr[3] = s3;
              potArr[3].x = x;
              potArr[3].y = y;
            }
          }

        }
      }
    }
    return potArr;
  }

  /**
     * 轮廓识别,使用最外轮廓发抽取轮廓RETR_EXTERNAL,轮廓识别方法为CHAIN_APPROX_SIMPLE
     *
     * @param source 传入进来的图片Mat对象
     * @return 返回轮廓结果集
     */
  public static Vector<MatOfPoint> findContours(Mat source) {
    Mat rs = new Mat();
    /**
         * 定义轮廓抽取模式
         *RETR_EXTERNAL:只检索最外面的轮廓;
         *RETR_LIST:检索所有的轮廓,并将其放入list中;
         *RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
         *RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。
         */
    /**
         * 定义轮廓识别方法
         * 边缘近似方法(除了RETR_RUNS使用内置的近似,其他模式均使用此设定的近似算法)。可取值如下:
         *CV_CHAIN_CODE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
         *CHAIN_APPROX_NONE:将所有的连码点,转换成点。
         *CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
         *CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS:使用the flavors of Teh-Chin chain近似算法的一种。
         *LINK_RUNS:通过连接水平段的1,使用完全不同的边缘提取算法。使用CV_RETR_LIST检索模式能使用此方法。
         */
    Vector<MatOfPoint> contours = new Vector<MatOfPoint>();
    Imgproc.findContours(
      source,
      contours,
      rs,
      Imgproc.RETR_LIST,
      Imgproc.CHAIN_APPROX_SIMPLE
    );
    return contours;
  }

  /**
     * 计算两点之间的距离
     *
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
  private static int getSpace(int x1, int y1, int x2, int y2) {
    int xspace = Math.abs(x1 - x2);
    int yspace = Math.abs(y1 - y2);
    return (int) Math.sqrt(Math.pow(xspace, 2)   Math.pow(yspace, 2));
  }
}

处理全流程

代码语言:javascript复制
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import utils.opencv.ContoursUtils;
import utils.opencv.OpenCVUtil;
import utils.opencv.WarpPerspectiveUtils;

import java.util.Vector;


public class Test01 {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static void main(String[] args) {
        String basepath = "D:\Project\Java\opencv-demo01\pic\";

        // 以灰度方式,读取图片
        Mat img = Imgcodecs.imread(basepath   "0.jpg", Imgcodecs.IMREAD_GRAYSCALE);
        Imgcodecs.imwrite(basepath   "1.png", img);

        // 转成二值化图片
        Mat img2 = new Mat();
        Imgproc.threshold(img, img2, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
        Imgcodecs.imwrite(basepath   "2.png", img2);

        // 透视变形
        Mat img3 = WarpPerspectiveUtils.warpPerspective(img2, ContoursUtils.getAllPoints(img2));
        Imgcodecs.imwrite(basepath   "3.png", img3);

        // 膨胀
        Mat img4 = OpenCVUtil.eroding(img3);
        Imgcodecs.imwrite(basepath   "4.png", img4);

        // 截取选择题区域
        Rect rect = new Rect(68, 834, 1536, 220);
        Mat img5 = new Mat(img4, rect);
        Imgcodecs.imwrite(basepath   "5.png", img5);

        // 获取边界
        Vector<MatOfPoint> rectVec = ContoursUtils.findContours(img5);
        Vector<MatOfPoint> rectVec2 = new Vector<>();
        for (MatOfPoint matOfPoint : rectVec) {
            Rect rect2 = Imgproc.boundingRect(matOfPoint);
            if (rect2.width > 36 && rect2.height > 20 && rect2.width < 50 && rect2.height < 40) {
                rectVec2.add(matOfPoint);
            }
        }
        Mat img6 = new Mat(img5.rows(), img5.cols(), CvType.CV_8UC3, new Scalar(255, 255, 255));
        Imgproc.drawContours(img6, rectVec2, -1, new Scalar(0, 0, 255), 1);
        Imgcodecs.imwrite(basepath   "6.png", img6);
    }
}

绘图

画线

代码语言:javascript复制
String basePath = "D:\Project\Java\opencv-demo01\pic\";

Scalar bgColor = new Scalar(255, 255, 255, 0); // B G R 0  白色
Scalar color = new Scalar(0, 0, 255, 0); // B G R 0 红色
Mat img01 = new Mat(new Size(400, 500), CvType.CV_8UC3, bgColor);
Imgproc.line(
  img01,
  new Point(11, 22),
  new Point(220, 330),
  color,
  1,
  Imgproc.LINE_AA
);
Imgcodecs.imwrite(basePath   "line.png", img01);

说明

参数

解释

InputOutPutArray img

在 img 图像上绘制

Point pt1

端点1

Point pt2

端点2

Scalar& color

颜色

int thickness

线条厚度

lineType

线条边缘类型(LINE_4(边缘像素采用4连通,即上下左右),LINE_8(边缘像素采用8连通,即上下左右还有四个对角),LINE_AA(边缘像素采用高斯滤波,抗锯齿))

画椭圆

代码语言:javascript复制
String basePath = "D:\Project\Java\opencv-demo01\pic\";

Scalar bck = new Scalar(255, 255, 255, 0); // B G R 0  白色
Scalar scalar = new Scalar(0, 0, 255, 0); // B G R 0 红色
Mat img01 = new Mat(new Size(400, 500), CvType.CV_8UC3, bck);
Imgproc.ellipse(img01, new Point(256, 256), new Size(100, 50), 0, 0, 360, scalar);
Imgcodecs.imwrite(basePath   "ellipse.png", img01);

矩形

代码语言:javascript复制
String basePath = "D:\Project\Java\opencv-demo01\pic\";

Scalar bck = new Scalar(255, 255, 255, 0); // B G R 0  白色
Scalar scalar = new Scalar(0, 0, 255, 0); // B G R 0 红色
Mat img01 = new Mat(new Size(400, 500), CvType.CV_8UC3, bck);
Imgproc.rectangle(img01, new Point(100, 20), new Point(310, 148), scalar);
Imgcodecs.imwrite(basePath   "rectangle.png", img01);

圆圈

代码语言:javascript复制
String basePath = "D:\Project\Java\opencv-demo01\pic\";

Scalar bck = new Scalar(255, 255, 255, 0); // B G R 0  白色
Scalar scalar = new Scalar(0, 0, 255, 0); // B G R 0 红色
Mat img01 = new Mat(new Size(400, 500), CvType.CV_8UC3, bck);
Imgproc.circle(img01, new Point(100, 100), 63, scalar);
Imgcodecs.imwrite(basePath   "circle.png", img01);

文本

代码语言:javascript复制
String basePath = "D:\Project\Java\opencv-demo01\pic\";

Scalar bck = new Scalar(255, 255, 255, 0); // B G R 0  白色
Scalar scalar = new Scalar(0, 0, 255, 0); // B G R 0 红色
Mat img01 = new Mat(new Size(400, 500), CvType.CV_8UC3, bck);
Imgproc.putText(
  img01,
  "Hello Word",
  new Point(10, 100),
  Imgproc.FONT_HERSHEY_SIMPLEX,
  2,
  scalar,
  2,
  Imgproc.LINE_AA,
  false
);
Imgcodecs.imwrite(basePath   "text.png", img01);

要将文本放入图像中,需要指定以下内容。

  • 您要写入的文字数据
  • 您要放置它的位置坐标(即文字的左下角)。
  • 字体类型
  • 字体比例(指定字体大小)
  • 线条类型 为了获得更好的外观,建议使用LINE_AA

0 人点赞