A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 小影姐姐 黑马粉丝团   /  2018-4-9 16:51  /  2340 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 上海分校-小影 于 2018-4-9 16:53 编辑

OpenCV概述应用领域
1、人机互动2、物体识别3、图像分割4、人脸识别5、动作识别6、运动跟踪7、机器人8、运动分析9、机器视觉
OpenCV做为功能强大的计算机视觉开源框架,包含了500多个算法实现,而且还在不断增加,其最新版本已经更新到3.2。其SDK支持Android与Java平台开发,对于常见的图像处理需求几乎都可以满足,理应成为广大Java与Android程序员的首先的图像处理框架。Java中使用OpenCV的配置及其简单,可以毫不客气的说几乎是零配置都可以。
一:配置
配置引入OpenCV相关jar包,首先要下载OpenCV的自解压版本,下载地址: http://opencv.org/opencv-3-2.html 然后拉到网页的最下方,下载Windows自解压开发包
下载好了双击解压缩之后找到build路径,显示如下:
双击打开Java文件夹,
里面有一个jar直接导入到Eclipse中的新建项目中去, 然后把x64里面的dll文件copy到Eclipse中使用的Java JDK bin和jre/bin目录下面即可。环境就配置好啦,简单吧!配置好的最终项目结构:
二:加载图像与像素操作
读入一张图像 -, 一句话搞定Mat src = Imgcodecs.imread(imageFilePath);if(src.empty()) return;
将Mat对象转换为BufferedImage对象public BufferedImage conver2Image(Mat mat) {
[AppleScript] 纯文本查看 复制代码
int width = mat.cols();
int height = mat.rows();
int dims = mat.channels();
int[] pixels = new int[width*height];
byte[] rgbdata = new byte[width*height*dims];
mat.get(0, 0, rgbdata);
BufferedImage image = new BufferedImage(width, height, 
                        BufferedImage.TYPE_INT_ARGB);
int index = 0;
int r=0, g=0, b=0;
for(int row=0; row<height; row++) {
    for(int col=0; col<width; col++) {
        if(dims == 3) {
            index = row*width*dims + col*dims;
            b = rgbdata[index]&0xff;
            g = rgbdata[index+1]&0xff;
            r = rgbdata[index+2]&0xff;
            pixels[row*width+col] = ((255&0xff)<<24) | 
            ((r&0xff)<<16) | ((g&0xff)<<8) | b&0xff;    
        }
        if(dims == 1) {
            index = row*width + col;
            b = rgbdata[index]&0xff;
            pixels[row*width+col] = ((255&0xff)<<24) | 
            ((b&0xff)<<16) | ((b&0xff)<<8) | b&0xff;    
        }
    }
}
setRGB( image, 0, 0, width, height, pixels);
return image;
}
将BufferedImage对象转换为Mat对象public Mat convert2Mat(BufferedImage image) {

[AppleScript] 纯文本查看 复制代码
int width = image.getWidth();
int height = image.getHeight();
Mat src = new Mat(new Size(width, height), CvType.CV_8UC3);
int[] pixels = new int[width*height];
byte[] rgbdata = new byte[width*height*3];
getRGB( image, 0, 0, width, height, pixels );
int index = 0, c=0;
int r=0, g=0, b=0;
for(int row=0; row<height; row++) {
    for(int col=0; col<width; col++) {
        index = row*width + col;
        c = pixels[index];
        r = (c&0xff0000)>>16;
        g = (c&0xff00)>>8;
        b = c&0xff;        index = row*width*3 + col*3;
        rgbdata[index] = (byte)b;
        rgbdata[index+1] = (byte)g;
        rgbdata[index+2] = (byte)r;
    }
}
​
src.put(0, 0, rgbdata);
return src;
}
特别要说明一下,BufferedImage与Mat的RGB通道顺序是不一样,正好相反,在Mat对象中三通道的顺序为BGR而在BufferedImage中为RGB。从Mat中读取全部像素(其中image为Mat类型数据)int width = image.cols();int height = image.rows();int dims = image.channels();byte[] data = new byte[widthheightdims];image.get(0, 0, data);
遍历像素操作与保存改变

[AppleScript] 纯文本查看 复制代码
int index = 0;int r=0, g=0, b=0;for(int row=0; row<height; row++) {
for(int col=0; col<width*dims; col+=dims) {
    index = row*width*dims + col;
    b = data[index]&0xff;
    g = data[index+1]&0xff;
    r = data[index+2]&0xff;
    r = 255 - r;
    g = 255 - g;
    b = 255 - b;
​
    data[index] = (byte)b;
    data[index+1] = (byte)g;
    data[index+2] = (byte)r;
}
}image.put(0, 0, data);
保存Mat对象为图像文件 - 一句话可以搞定

Imgcodecs.imwrite(filePath, src); 三:OpenCV代码运行与测试
调节明暗程度 - 亮度降低
调节明暗程度 - 亮度提升
高斯模糊
锐化
梯度
灰度化
上述效果完整Java代码如下:package com.gloomyfish.opencvdemo;import org.opencv.core.Core;import org.opencv.core.CvType;import org.opencv.core.Mat;import org.opencv.core.Size;import org.opencv.imgproc.Imgproc;
public class ImageFilters {

[AppleScript] 纯文本查看 复制代码
/** - 反色处理 - */
public Mat inverse(Mat image) {
    int width = image.cols();
    int height = image.rows();
    int dims = image.channels();
    byte[] data = new byte[width*height*dims];
    image.get(0, 0, data);
​
    int index = 0;
    int r=0, g=0, b=0;
    for(int row=0; row<height; row++) {
        for(int col=0; col<width*dims; col+=dims) {
            index = row*width*dims + col;
            b = data[index]&0xff;
            g = data[index+1]&0xff;
            r = data[index+2]&0xff;
​
            r = 255 - r;
            g = 255 - g;
            b = 255 - b;
​
            data[index] = (byte)b;
            data[index+1] = (byte)g;
            data[index+2] = (byte)r;
        }
    }
​
    image.put(0, 0, data);
    return image;
}
​
public Mat brightness(Mat image) {
    // 亮度提升
    Mat dst = new Mat();
    Mat black = Mat.zeros(image.size(), image.type());
    Core.addWeighted(image, 1.2, black, 0.5, 0, dst);
    return dst;
}
​
public Mat darkness(Mat image) {
    // 亮度降低
    Mat dst = new Mat();
    Mat black = Mat.zeros(image.size(), image.type());
    Core.addWeighted(image, 0.5, black, 0.5, 0, dst);
    return dst;
}
​
public Mat gray(Mat image) {
    // 灰度
    Mat gray = new Mat();
    Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);
    return gray;
}
​
public Mat sharpen(Mat image) {
    // 锐化
    Mat dst = new Mat();
    float[] sharper = new float[]{0, -1, 0, -1, 5, -1, 0, -1, 0};
    Mat operator = new Mat(3, 3, CvType.CV_32FC1);
    operator.put(0, 0, sharper);
    Imgproc.filter2D(image, dst, -1, operator);
    return dst;
}
​
public Mat blur(Mat image) {
    // 高斯模糊
    Mat dst = new Mat();
    Imgproc.GaussianBlur(image, dst, new Size(15, 15), 0);
    return dst;
}
​
​
public Mat gradient(Mat image) {
    // 梯度
    Mat grad_x = new Mat();
    Mat grad_y = new Mat();
    Mat abs_grad_x = new Mat();
    Mat abs_grad_y = new Mat();
​
    Imgproc.Sobel(image, grad_x, CvType.CV_32F, 1, 0);
    Imgproc.Sobel(image, grad_y, CvType.CV_32F, 0, 1);
    Core.convertScaleAbs(grad_x, abs_grad_x);
    Core.convertScaleAbs(grad_y, abs_grad_y);
    grad_x.release();
    grad_y.release();
    Mat gradxy = new Mat();
    Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 10, gradxy);
    return gradxy;

}
}可以说简单到哭,此外OpenCV For Java支持各种的图像处理包括形态学操作,二值图像分析、图像特征检测与识别、模板匹配、直方图相关功能等等。常见的机器学习算法与图像分析方法。可以说是功能最强大的图像处理SDK与开发平台之一特别注意
在调用之前,一定要加上这句话System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
目的是加载OpenCV API相关的DLL支持,没有它是不会正确运行的。以上代码与功能实现是基于JDK8 64位与OpenCV 3.2版本。

2 个回复

倒序浏览
厉害厉害
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马