OpenCV4.0 与 Processing 图像格式分析和转换

栏目: 编程工具 · 发布时间: 5年前

内容简介:目前主要通过Processing作为交互界面,所有的图像最后要通过Processing展示。一、Processing图像的使用格式首先,看Processing的图像对格式的要求。

目前主要通过Processing作为交互界面,所有的图像最后要通过Processing展示。

一、Processing图像的使用格式

首先,看Processing的图像对格式的要求。

Processing的图像使用 PImage 类封装(有图有真相)。

OpenCV4.0 与 Processing 图像格式分析和转换

这是 PImage 的缺省构造方法,默认的图像格式就是 ARGB,也就是使用4个通道表达图像的像素 (alpha, red, green, and blue)

OpenCV4.0 与 Processing 图像格式分析和转换

这是检查图像的像素,如果任何一个像素包含 alpha 通道(透明度),则格式设定为 ARGB !

这里展示的这两个方法,想表达的意思是: Processing 环境下,需要的图像格式的正确顺序是  ARGB ,请记住这个顺序!

二、OpenCV使用的图像格式

问题来了:point_down:

OpenCV使用的图像格式是 BGR ! 为什么?

早期开发者使用BGR作为颜色的空间的原因在于:那个时候的BGR格式在相机制造厂商和软件提供商之间比较受欢迎。

例如:在Windows中,当使用 COLORREF 指定颜色值时,使用BGR格式0x00bbggrr。

更多看这里  --> https://www.learnopencv.com/why-does-opencv-use-bgr-color-format/

前面的OpenCV4从摄像头获取的视频数据,每一帧都是BGR的格式。

虽然 OpenCV4提供了图像格式转换类 Imgproc ( 官方Java doc ),提供了大量的图像格式转换方法(下面是其中的一部分),

static int COLOR_mRGBA2RGBA
static int COLOR_RGB2BGR
static int COLOR_RGB2BGR555
static int COLOR_RGB2BGR565
static int COLOR_RGB2BGRA
static int COLOR_RGB2GRAY
static int COLOR_RGB2HLS
static int COLOR_RGB2HLS_FULL
static int COLOR_RGB2HSV
static int COLOR_RGB2HSV_FULL
static int COLOR_RGB2Lab
static int COLOR_RGB2Luv
static int COLOR_RGB2RGBA
static int COLOR_RGB2XYZ
static int COLOR_RGB2YCrCb
static int COLOR_RGB2YUV
static int COLOR_RGB2YUV_I420
static int COLOR_RGB2YUV_IYUV
static int COLOR_RGB2YUV_YV12
static int COLOR_RGBA2BGR
static int COLOR_RGBA2BGR555
static int COLOR_RGBA2BGR565
static int COLOR_RGBA2BGRA
static int COLOR_RGBA2GRAY
static int COLOR_RGBA2mRGBA
static int COLOR_RGBA2RGB
static int COLOR_RGBA2YUV_I420
static int COLOR_RGBA2YUV_IYUV
static int COLOR_RGBA2YUV_YV12

但是,没有直接将 BGR格式直接转换为 ARGB 格式的方法!

前面的程序使用: Imgproc.cvtColor(tmp, src, Imgproc.COLOR_BGR2RGBA);

只能将图像格式从BGR装换到 RGBA,而Processing需要的格式是 ARGB !

这就是导致上一篇文章中图像颜色失真的原因了!

三、解决方法

OpenCV提供了一个混合(颜色)通道的方法  Core.mixChannels( ),可以实现不同通道的颜色交换!

就是他了!

1、原来的方法

draw( )方法如下:

void draw() {
  background(0);
  Mat tmp = new Mat();
  cap.read(tmp);
  Imgproc.cvtColor(tmp, fm, Imgproc.COLOR_BGR2RGBA);
  PImage img = matToImg(fm);
  image(img, 0, 0);
  tmp.release();
}

2、修改后的方法

draw() 方法如下:

void draw() {
  background(0);
  Mat tmp = new Mat();
  Mat src = new Mat();
  cap.read(tmp);
  Imgproc.cvtColor(tmp, src, Imgproc.COLOR_BGR2RGBA);
  fm = src.clone();
  ArrayList<Mat> srcList = new ArrayList<Mat>();
  ArrayList<Mat> dstList = new ArrayList<Mat>();
  Core.split(src, srcList);
  Core.split(fm, dstList);
  Core.mixChannels(srcList, dstList, new MatOfInt(0, 1, 1, 2, 2, 3, 3, 0));
  Core.merge(dstList, fm);
  PImage img = matToImg(fm);
  image(img, 0, 0);
  src.release();
  tmp.release();
}

三、解释一下

1、创建两个空矩阵 src、tmp;

Mat tmp = new Mat();
Mat src = new Mat();

2、将图像的一帧数据读入 tmp 矩阵;

cap.read(tmp);

3、将 tmp 矩阵的图像格式由 BGR 转换为 RGBA,保存到 src 中;

Imgproc.cvtColor(tmp, src, Imgproc.COLOR_BGR2RGBA);

4、克隆一个 src 为 fm;

fm = src.clone();

这时候,src 和 fm 的内容相同的、都是转换成 RGBA 格式的图像信息;

5、创建两个ArrayList ,把两个矩阵src和fm转换成一维数组srcList和dstList;

ArrayList<Mat> srcList = new ArrayList<Mat>();
ArrayList<Mat> dstList = new ArrayList<Mat>();
Core.split(src, srcList);
Core.split(fm, dstList);

6、使用Core.mixChannels() 交换两个一维数组指定位置的数据,将RGBA 的数据交换成 ARGB 数据( 后面说怎么指定位置 )把需要的数据保存到 dstList 中;

Core.mixChannels(srcList, dstList, new MatOfInt(0, 1, 1, 2, 2, 3, 3, 0));

这时候,dstList 一维数组保存的是交换后的 AGRB 数据;

7、然后把 dstList 保存到 fm 矩阵中。

Core.merge(dstList, fm);

8、把 fm矩阵数据转换为PImage。

PImage img = matToImg(fm);

9、显示 PImage 图像。

image(img, 0, 0);

四、OpenCV提供的方法

前面三段中第3步和第6步,都是使用OpenCV提供的方法完成

A)由 BGR 转换为 RGBA;

B)交换一维数组指定位置的数据;

下面用数据进行黑盒测试,看看这两个方法的效果。

1、测试 Imgproc.cvtColor()将 BGR 转换为 RGBA

创建一个空矩阵 src ,一个tmp 矩阵设置一些模拟数据;

import org.opencv.core.*;
import org.opencv.videoio.*;
import org.opencv.imgproc.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;

void setup(){
  size(640,480);
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  noLoop();
}

void draw(){
  background(0);
  Mat src = new Mat();
  Mat tmp = new Mat(new Size(4,3),CvType.CV_8UC4,new Scalar(1,2,3,4));
  println("----- before ---");
  println("src  --->");
  println(src.dump()+"\n");
  println("tmp  --->");
  println(tmp.dump()+"\n");
  Imgproc.cvtColor(tmp, src, Imgproc.COLOR_BGR2RGBA);
  println("----- after ---\n");
  println("src  --->");
  println(src.dump()+"\n");
  println("tmp  --->");
  println(tmp.dump());
}

结果:

OpenCV4.0 与 Processing 图像格式分析和转换

可以看出,经过 Imgproc.cvtColor(),tmp的 BGRA 格式转换成了 RGBA格式。

2、交换一维数组指定位置的数据

模拟两个矩阵数据,转换成一维数组

import org.opencv.core.*;
import org.opencv.videoio.*;
import org.opencv.imgproc.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;

void setup(){
  size(640,480);
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  noLoop();
}

void draw(){
  background(0);
  
  Mat src = new Mat(new Size(4,3),CvType.CV_8UC4,new Scalar(0,1,2,3));
  Mat fm = new Mat(new Size(4,3),CvType.CV_8UC4,new Scalar(0,1,2,3));
  
  println("----- before ---");
  println("src  --->");
  println(src.dump()+"\n");
  println("fm  --->");
  println(fm.dump()+"\n");
  
  ArrayList<Mat> srcList = new ArrayList<Mat>();
  ArrayList<Mat> dstList = new ArrayList<Mat>();
  Core.split(src, srcList);
  Core.split(fm, dstList);
  
  Core.mixChannels(srcList, dstList, new MatOfInt(0, 1, 1, 2, 2, 3, 3, 0));
  Core.merge(dstList, fm);
  
  println("----- after ---\n");
  println("src  --->");
  println(src.dump()+"\n");
  println("fm  --->");
  println(fm.dump());
}

调用 Core.mixChannels(srcList, dstList, new MatOfInt(0, 1, 1, 2, 2, 3, 3, 0));    方法得出:

OpenCV4.0 与 Processing 图像格式分析和转换

数据从 RGBA 转换为 ARGB。

从上面这张图,讲一下 MatOfInt(0,1,1,2,2,3,3,0)的作用。

把 MatOfInt 的参数,两两一对,组成 (0,1)  (1,2)  (2,3)  (3,0)

表示:

(0,1)   R 从 源通道0 -->目标通道1,

(1,2)   G 从 源通道1-->目标通道2,

(2,3)   B 从 源通道2 -->目标通道3,

(3,0)  A 从 源通道3 -->目标通道0

五、结论

只要通过OpenCV的两个方法Imgproc.cvtColor()和Core.mixChannels()方法组合,可以将OpenCV的 BGR格式转换成Processing需要的 ARGB格式。

只要理解了OpenCV的 BGR 格式,Processing的ARGB格式,就可以更好的利用API对图像、视频进行处理。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java算法

Java算法

塞奇威克 / 赵文进 / 清华大学出版社 / 2004-06-01 / 59.0

《Java算法》用Java语言全面实现了当今最重要的计算机算法,并用大量图表和数学公式对算法进行了详尽的描述和分析。全书共分3卷,本书是其中的第1卷(第1至第4部分)。内容包括基本概念(第1部分)、数据结构(第2部分)、排序算法(第3部分)和查找算法(第4部分)。本书概念清楚,内容翔实,新颖,由浅入深地描述了算法。本书可作为高等院校计算机相关专业本科生和研究生的教材和补充读物,也可作为Java爱好一起来看看 《Java算法》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具