成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文弄明白 OpenCV Mat 中通道channels的作用

開發 前端
在網上找到有很多是C語言寫的。在這里我想使用java的語法給大家介紹一下。如何通過Mat獲取到指定區域的像素。RGB,BGR,HSV,GRAY等格式數據的獲取。

1. 介紹

openCV 是使用 Mat 進行存儲圖片,記錄各種像素信息。那么 Mat 中的像素是如何記錄和獲取的呢?

在網上找到有很多是C語言寫的。在這里我想使用java的語法給大家介紹一下。

如何通過Mat獲取到指定區域的像素。RGB,BGR,HSV,GRAY等格式數據的獲取。

2. channels 通道

當我們使用Mat.channels() 方法,能夠得到當前 Mat 的通道數。 通常返回結果值為:1,2,3,4 這四個結果。

那么這個通道是什么東西呢?

我們知道,所有的圖像都是由一個個像素點堆積而成的。而一個像素點,又是由RGB顏色混合而成的。

每一種顏色就是一種通道。每個像素點是多個通道顏色的混合結果。

PS:知識點,RGB三原色可以混淆所有我們肉眼可以見到的顏色。

所以,當我們弄明白通道之后就能明白如何獲取Mat中指定坐標的顏色值了。

mat.rows() 是Y軸長度。

mat.cols() 是X軸長度。

示例:

Mat rgba ;// 假如我有一個 rgba的Mat對象
int channels = rgba.channels(); // channels 的長度是4
double[] temp = rgba.get(rgba.rows() / 2, rgba.cols() / 2); //取中間點顏色值
//temp 的數組的長度就是通道數,所以它的length=4

當我們遍歷一遍temp的結果會得到:

StringBuffer stringBuffer = new StringBuffer();
for (double s : temp) {
stringBuffer.append(s).append(",");
}
Log.e("TAG", "顏色值:" + stringBuffer);

//輸出:
顏色值:3.0,0.0,4.0,255.0,

數據的結果實際情況是:

  • r:3.0
  • g:0.0
  • b:4.0
  • a:255  (透明度,0表示透明,255表示不透明)

知識點,OpenCV 中的顏色順序不是 BGR 格式么?這個順序不針對 Mat 中的顏色,而是我們使用 Scalar 的時候傳入的顏色順序是 BGR 順序而已。

new Scalar(10,255,255); //顏色順序是 B,G,R

我們如果是一個 BGR 格式的 Mat 對象那么顏色值會怎么顯示呢?

還是使用上面的 Mat 我們進行轉換之后,看看同一個點輸出的結果:

Mat bgr=new Mat();
Imgproc.cvtColor(rgba, bgr, Imgproc.COLOR_RGB2BGR);// 將RGB格式轉為BGR格式
int channels = bgr.channels(); // channels 的長度是3
double[] temp1 = bgr.get(bgr.rows() / 2, bgr.cols() / 2); //取中間點顏色值
StringBuffer stringBuffer1 = new StringBuffer();
for (double s : temp1) {
stringBuffer1.append(s).append(",");
}
Log.e("TAG", "顏色值:" + stringBuffer1);

//輸出:
顏色值:4.0,0.0,3.0

數據的結果實際情況是:

  • b:4.0
  • g:0.0
  • r:3.0

就會出現顏色的通道數變化。

不知道注意到了沒有,我上面是將rbga直接轉成了BGR。

在高位轉換的情況下,A通道會被直接丟棄。體現在圖像上就會沒有透明效果了。

我們如果想確保A通道也轉換,可以使用:

Imgproc.cvtColor(rgba, bgra, Imgproc.COLOR_RGBA2BGRA);

2.1 Gray 灰度圖轉換

當我們將RGBA或者BGR等彩色圖像轉換為GRAY灰色的時候,Mat的通道數就會被壓制為單通道G了。效果如下:

int channels = rgba.channels();
double[] temp = rgba.get(rgba.rows() / 2, rgba.cols() / 2); //取中間點顏色值
// temp的長度就是 channels的值,所以temp的結果就是4
StringBuffer stringBuffer = new StringBuffer();
for (double s : temp) {
stringBuffer.append( s).append(",");
}
Log.e("TAG", "通道數:" + channels + " 顏色值:" + stringBuffer);

Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGBA2GRAY); //將RGBA轉GRAY
channels = rgba.channels();
temp = rgba.get(rgba.rows() / 2, rgba.cols() / 2); //取中間點顏色值
stringBuffer = new StringBuffer();
for (double s : temp) {
stringBuffer.append(s).append(",");
}
Log.e("TAG", "變換后:通道數:" + channels + " 顏色值:" + stringBuffer);

//輸出結果:
E/TAG: 通道數:4 顏色值:43.0,48.0,69.0,255.0,
E/TAG: 變換后:通道數:1 顏色值:49.0,

會發現灰色圖是只有一個通道的。

按照Gray = R*0.299 + G*0.587 + B*0.114 公式進行的轉換。

這個公式叫做Luminosity(亮度算法)。這個算法中RGB的各占比例。都是一個經驗值。也就是說沒有科學道理。純粹經驗出發調試出來的一個比例。

PS:所以有一個小常識,RGB轉Gray,然后再Gray轉換回RGB會出現色差。因為在轉換過程中避免不了信息丟失。

2.2 小結

當我們弄明白通道數的概念之后。就能夠弄明白cvtColor中的各種轉換了

Luv,Lab,HSV,RGB,BGR,HLS,YUV,GRAY等等的顏色轉換其實都是針對我們的單像素中的通道值在處理。

  1. 單通道的,是Gray灰度圖。
  2. 雙通道的,兩個通道值一個為實數,個為虛數。主要是RGB555和RGB565格式的圖像,這個通道通常用來計算。
  3. 三通道的,圖片就是彩色圖像了,例如RGB,BGR,HSV,HLS等等。
  4. 四通道的,圖片帶透明度的圖像了。相較于三通道多了一個alpha通道,也就是表示透明度。

我們在使用OpenCV時,新手經常出現Mat錯誤,就在于通道轉換了。因為OpenCV有些算法是必須單通道的。而我們一不小心傳了3通道的。或者,Mat是三通道的。與另一個單通道的Mat進行比較處理時,出現通道錯誤等等。

注意:

我們使用Imgproc.cvtColor?方法進行轉換的時候。輸入的Imgproc.COLOR_RGBA2GRAY等等值是很重要的。需要根據我們的Mat的實際情況進行選擇。

我們如果Mat是BGR格式的,我們卻選擇使用Imgproc.COLOR_RGB2HSV_FULL轉換,雖然結果是轉換了。但是實際情況是不對的。

因為Imgproc會按照RGB的順序從double[]數組中提取參數進行計算處理,而不是按照BGR的格式進行提取轉換。

2.2.1 Imgproc.COLOR_XXXX解釋

簡單介紹下ImgProc.COLOR_XXX的信息。其實說破很簡單:

ImgProc.COLOR_BGR2BGRA;// BGR to BGRA 也就是BGR格式轉BGRA格式
ImgProc.COLOR_RGB2RGBA;// RGB to RGBA 也就是RGB格式轉RGBA格式
ImgProc.COLOR_BGRA2BGR;// BGRA to BGR 格式
ImgProc.COLOR_RGBA2BGR;// RGBA to BGR 格式
ImgProc.COLOR_BGRA2GRAY;// BGRA to GRAY 格式
ImgProc.COLOR_RGB2HSV;// RGB to HSV格式 H的范圍值是0-180
ImgProc.COLOR_RGB2HSV_FULL;// RGB to HSV_FULL格式 H的范圍值是0-360 (PS:FULL獲取更大的精度,消耗更多的內存)

其他的就不介紹了,命名中的2代表to。然后將左邊的顏色格式轉為右邊的顏色格式而已。

3. 通道分解和合成

我們如果想操作通道。有很多方法,最簡單的是我們直接遍歷然后修改通道參數:

Mat det;
double [] temp;
for(int y=0;y<det.cols();++y){
for(int x=0;x<det.rows();++x){
temp = det.get(x,y);
//根據通道情況,修改值
}
}

或者,我們直接修改指定位置的顏色值:mat.put(x,y,temp);

而我們如果想批量針對通道進行操作,可以使用OpenCV提供的算法:

Core.split(); //分解通道
Core.merge(); //合成通道
Core.mixChannels(); //通道拆分復制 上面兩個分解和合成是該函數的一種特例場景。

下面來介紹這三個方法的傳值:

Core.split(Mat m, List<Mat> mv) 
//Mat m :需要進行通道分解的源Mat
//List<Mat> mv: 將源Mat的每個通道拆解為單通道的Mat,我們如果直接將該List中的Mat進行顯示將會全部是灰色的(因為是單通道了)

使用:

List<Mat> defList=new ArrayList<>();
Core.split(rgba,defList);
for(Mat mat:defList){
//我們得到的都是單通道的Mat。 如果直接轉Bitmap顯示 將只會看到灰度圖
}

我們如果想只想看到Mat中的紅色通道的效果,而不是看灰度圖。該怎么處理?

需要結合split方法和merge方法一起使用

Core.merge(List<Mat> mv, Mat dst)
//List<Mat> mv: 需要合并的Mat的集合,會將全部的mat的通道合并到dst中去 List中的Mat 必須寬高相同,
//dst:輸出的Mat:它的寬高必須和List中的Mat的寬高相同。而通道數會是List中所有Mat的通道數的總和

使用:將上面split拆解的Mat進行合并

//創建單通道 CvType.CV_8UC1
Mat blackMat = new Mat(rgba.size(), CvType.CV_8UC1, new Scalar(0)); //繪制一個全黑的Mat
List<Mat> mergeList = new ArrayList<>();
//創建一個3通道的 Mat對象
Mat dst = new Mat(rgba.size(), CvType.CV_8UC3);
mergeList.add(blackMat); //B 通道黑色
mergeList.add(blackMat); //G 通道黑色
mergeList.add(defList.get(0));// R通道
Core.merge(mergeList, dst);

最終我們得到的dst就是一個三通道的圖像了,只有R通道有值。(圖片是BGR的順序存儲的)

4. 總結

到這里關于通道的介紹就結束了。以上內容基于自己的理解和驗證。在openCV4.6 SDK版本,java開發環境下進行的驗證。

責任編輯:武曉燕 來源: zinyan
相關推薦

2023-03-13 08:12:37

Golang編程路徑問題

2020-07-10 08:03:35

DNS網絡ARPAne

2019-08-27 14:46:59

ElasticSearES數據庫

2024-05-13 10:45:25

中介模式面向對象數量

2024-05-10 08:43:04

外觀模式接口系統

2024-05-09 09:09:19

組合模式對象

2021-05-06 08:03:07

IPIP網絡模式calicok8s

2024-05-11 14:18:44

迭代器模式業務

2023-05-29 08:45:45

Java注解數據形式

2024-05-17 10:08:59

享元模式分類方式

2022-06-09 08:17:30

Python__new__

2023-03-17 08:00:34

OpenCVCvType錯誤

2024-05-15 17:41:37

備忘錄模式多線程

2022-03-18 09:45:43

Git分支Linux

2023-04-18 08:10:10

2021-06-06 13:06:34

JVM內存分布

2022-10-28 13:48:24

Notebook數據開發機器學習

2023-07-04 08:56:07

指針類型Golang

2021-10-28 10:26:35

Javascript 高階函數前端

2019-09-09 11:02:17

Nginx進程模型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线视频 亚洲 | 欧美乱大交xxxxx另类电影 | 欧美一区二区三区四区视频 | 日韩在线视频观看 | 国产一区二区视频免费在线观看 | 亚洲男女视频在线观看 | 中文成人在线 | 91免费观看视频 | 天天玩天天操天天干 | 久久久精品 | 国产中文区二幕区2012 | 日韩精品一区二区三区第95 | 日韩一区中文字幕 | 激情五月婷婷 | av黄色免费 | 91麻豆久久久 | 亚洲男人网 | 国产黄色av网站 | 中文字幕av色 | 国产女人精品视频 | 国产欧美一区二区三区免费 | 久久久蜜桃| 狠狠爱综合 | 综合网伊人 | 国产色99精品9i | 国产精品久久影院 | 成人午夜免费视频 | 国产第二页 | 无人区国产成人久久三区 | av福利网| 久久99国产精品久久99果冻传媒 | 成人一区av偷拍 | 国产精品一区二区三区四区 | 欧美国产日本一区 | 精品久久久久久18免费网站 | 国产欧美一区二区久久性色99 | 欧美日韩久久 | 欧美高清视频 | 1级毛片| 高清av一区 | 玖玖操 |