在学习opencv的时候看到多通道矩阵这一概率,恳求大神告诉我一下啥意思
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在学习opencv的时候看到多通道矩阵这一概率,恳求大神告诉我一下啥意思相关的知识,希望对你有一定的参考价值。
指的是矩阵的元素有几个分量构成。比如矩阵的元素类型是Point3d那么它就是3通道的,因为Point3d是一个三维点(x,y,z),Size2f是2通道的,uchar就是单通道的。用矩阵表示一幅图像时,如uchar是1通道的灰度图像。彩色图像Vec3b是3通道的,含BGR分量 参考技术A 随着数字技术,硬件和软件水平的快速发展,已经有高性能DSP和高速总线被应用,基于数字技术,使视频矩阵解决方案可以实现。海康威视板生产线在不久的将来将推出一款新车型:DS4002MD,即矩阵解码卡,本产品的基础上,海康威视数字视频矩阵提出解决方案。同时,我们海康威视数字视频矩阵将在新兴安全产业的热点视频矩阵也将成为未来的趋势。
一,基本概念视频矩阵
1。视频矩阵的基本功能和要求
作为视频矩阵,最重要的功能是实现输入输出视频图像切换。准确概括那就是:将视频图像从任何输入通道的任何输出通道切换显示。在一般情况下,一个M×N的矩阵:M表示,它可以支持的图像输入信道和N沟道图像输出。应该强调的是,需要执行任何操作,也就是说,任何一个输入和一个任意的输出。
另外,矩阵系统通常应包括以下基本功能:字符信号叠加,解码器接口控制云台和摄像头,报警接口,控制面板,音频控制箱,报警接口箱,控制键盘等。附件。对于国内用户来说,应该所有汉字叠加利用运营商,以方便不懂英文,矩阵系统还需要支持级联,以实现更高的容量,以适应不同用户对矩阵系统容量的要求,矩阵系统应支持模块化和即插即用(PNP),可以增加或减少视频输入和输出卡的大小不同的组合。
矩阵系统的开发是一个多功能,高容量,并可以联网的远程开关。一般来说为64×16的矩阵系统容量的大容量的矩阵。如果你需要更大容量的矩阵系统,也可以是多矩阵系统级联来实现。矩阵更大的容量,更高的要求的技术水平,设计和实现的难度就越大。
2。分类
不同的方式来实现视频矩阵和矩阵视频矩阵视频切换?分为模拟数字矩阵。
模拟矩阵:
视频切换在模拟视频层完成。信号切换主要用于微控制器或更复杂的芯片控制模拟开关实现。
数字矩阵视频切换在数字视频层完成,这个过程可以是同步或异步。数字视频处理的数字矩阵的核心,它是需要增加的视频输入端子AD转换器,将模拟信号转换成数字信号,以增加DA转换,将数字信号转换成模拟信号输出的视频输出端子。从模拟的模拟开关的核心视频切换矩阵,变量将成为数字视频的处理和传输。
二,数字视频矩阵言
1。数字视频矩阵<br基于分类矩阵实现的数字视频,数字视频矩阵可以分为总线和数据包交换。总线
高清数字视频矩阵,矩阵?是通过共享总线来实现的,如PCI总线的数据总线型数字传输和交换。
总线矩阵?最常见的PC-DVR和嵌入式DVR。对于PC-DVR,视频输出VGA,通过PC显卡来完成图像的显示,通常只有1个输出(1视频)(2张),2输出的情况下,具有非常小的嵌入式DVR一般的视频输出显示器,一些新的嵌入式DVR,也可以支持VGA显示。另外,在上述的两个例子中,它们可以实现视频输出(也可以是分割画面),这两种产品可以用来作为一种特殊的情况下,视频矩阵,这是一个视频输出只有一个特例。
PC-DVR(PC + H卡,HC卡)组成的总线型数字矩阵
包交换数字视频矩阵
分组交换分组交换矩阵?实现的方式(通常是IP数据包),用于图像数据的传输和交换。分组交换矩阵是?现在比较流行的,如已被广泛用于远程监控中心,结束在本地视频图像的压缩,然后通过网络(可以是高速的专用网络,宽带压缩位流,LAN等)发送到远程,远程解码,显示在大屏幕上。数字分组交换矩阵有两个比较大的电流限制:延迟长,图像质量差。由于网络,因此不可避免地带来的延迟,并在编码时,为了降低对网络带宽的占用,往往需要在发送侧的图像压缩,解压缩在接收侧实现,以确保更好的图像质量通过有损压缩的图像,难以和解码过程也增加了延迟。因此,目前的分组交换矩阵也不太适合实时性能和图像质量要求比较高的场合。
分组交换的数字矩阵
三个数字视频矩阵优势
成本优势:视频矩阵和DVR
数字视频矩阵解决方案相结合,只需要一件设备可以同时实现视频矩阵和DVR的功能,大大节省了成本。矩阵和DVR的控制集成,方便,灵活的控制。如果您使用的模拟矩阵,至少有一个矩阵主机和DVR主机,安装和调试复杂,除了DVR的成本,而且还模拟矩阵付出高额的成本。此外,模拟矩阵的控制,可能还需要添加其他的设备,如显示装置,矩阵控制器,矩阵键盘,和一些复杂的功能,即使需要专用的PC上,以被配置。该方案还需要模拟矩阵视频信号的分配,复用设备来实现DVR的录像功能,而采用数字矩阵,DVR的简单的基础上,你可以添加一个简单的矩阵模块,成本相对较低,数字矩阵,视频系统集成,增强的稳定性,但也降低了未来的维修费用。
功能优势:配置灵活,功能强大,使用方便
+ DVR解决方案在模拟矩阵,矩阵和DVR各自为政,需要单独控制,模拟矩阵提供了复杂的操作模式,缓解不佳,并设有一个单一的,如果你想实现更复杂的功能,你需要一个非常复杂的操作过程,而采用数字矩阵,可以通过一个控制平台实现交换矩阵和DVR的同时控制,操作界面在Windows或二次开发Linux开发人员的自由,根据客户的需求定制应用程序,自定义各种功能,所构建的系统,完全取决于自己的软件开发商的。
数字矩阵,数字图像处理的基础上可以实现视频切换,而大量的图像处理,比如叠加字符,叠加图像,覆盖面积等这些都是现在普遍有一个DVR功能,但模拟矩阵,由于其核心是基于模拟信号处理,在面对这些功能,这似乎是不充分的。在这里,字符叠加功能,例如,往往需要外部模拟矩阵字符叠加芯片来实现,通常只能实现ASCII码是英文字符的叠加,可实现汉字叠加的模拟,可以说是寥寥无几,更不用提同样支持简体和繁体,甚至日文的。至于图像叠加功能,模拟信号层基本上是不可能实现的。
数字矩阵可以提供更丰富的图像显示模式。可以是传统的模拟矩阵简单的1:1的图像输出,也可以实现N→1(通过缩放图像处理的基础上,而数字矩阵,可以实现在一个窗口中显示多个图像)和1→N(显示输入图像同时显示多路输出),甚至画中画等先进功能。最后,系统的稳定性,数字矩阵+ DVR解决方案,系统集成,低功耗,高稳定性,同时使用模拟矩阵溶液,对多个设备的需要,问题的概率大大增加。
潜在空间巨大,开发
模拟矩阵控制系统已经非常成熟,其产品的结构和功能在最近几年,甚至十年,都没有太多改变,可挖掘的潜力已经非常有限的。
数字矩阵?完全不同,目前数字技术的发展可以用日新月异,前途广阔来形容。首先,随着硬件性能的提高在高速总线方面:66M的PCI总线已经很成熟和普及,比如PCI-E或其它的高速串行总线也不断提高,芯片技术已经出现600M,720M甚至是1GHz的高性能DSP,它可以说,得益于硬件平台性能的不断提高,势必使数字矩阵的功能不断升级,不断发展高端。与此同时,软件的进步同样不能被忽视,一直有新的图像压缩,处理算法提出增加图像压缩的效率,但也有更加复杂和智能图像处理算法得到应用,如智能运动检测,智能识别技术(人脸识别,指纹识别,车牌识别,签名识别)目前已经比较成熟的应用程序,这些更高层次的图像处理技术,使用当前的硬件平台,他们已经可以应用到我们的数字视频系统的介质。因此,软件和硬件水平快速增长,我们有理由相信,数字矩阵的发展空间将十分广阔,无论是在性能和全功能绑定在模拟矩阵。
二次开发简单,方便
卡和先前的H和D,分别使用他们的SDK卡,新的SDK将支持H卡,HC卡和MD卡。简单地通过一个软件开发工具包(SDK),可以实现编码,解码,和矩阵控制,一个新的编码的SDK,SDK解码单元和原始编码,解码单元兼容的用户可以简单地增加矩阵控制部分,一个伟大的降低了用户进行二次开发的复杂性。同时:H卡,HC卡和MD卡可以混合到现有项目和扩展,维护方便。
4个,海康威视数字视频矩阵解决方案
我们的数字视频矩阵解决方案是基于海康威视已经推出了HC系列压缩卡和即将发布的MD系列矩阵解码卡实现。 HC是负责系统的视频卡,预览,网络传输,这部分的应用已经非常成熟。而MD卡的关键是实现视频矩阵,MD卡解码卡实现所有原来的功能,增加输出的矩阵实现视频矩阵功能,而HC卡,MD卡,也可以独立,仅使用硬件解码器卡,通过网络连接,也可嵌入到一个远程视频服务器,它可以是海康威板设备构成的网络视频矩阵,这是相同的,并且原来的解码卡,但新卡的功能MD和D卡比较,将有大量的扩展,如解码的大大提高,原来的D卡只有一个DSP解决方案道路,但现在至少有四个可能的解决方案。随着多窗口分割画面功能,用户可以做的解码图象的输出的任何组合。额外的同步功能,可以同步解码器之间的亮。
1。其主要参数:
DS4002MD卡操作系统支持Windows2000/XP中,和Linux。
用作基质:
每张卡支持双通道4路矩阵输出,稳定的支持。
HC卡,可以实现64×4视频矩阵,同时保证实时压缩,64。
解码,:
解码功能,解码器卡,与原来的完全兼容。
每卡支持4通道解码(实时解码4路CIF,2CIF 4路或2路4CIF),2个模拟输出,支持多达64声道解码,32路模拟量输出。
2。 DS4002MD典型场景
⑴本地视频矩阵的形成,实时录音系统
在这个系统中,构成了由HC卡64路DVR系统,这是相同和本卡方案,除了增加2 MD卡,完成4个模拟输出,视频矩阵功能。
一个64×4矩阵+实时数字录像系统
⑵网络矩阵由16 DS4002MD
网络矩阵解码,同时支持64 - 和32路网络视频输出网络监控中心 参考技术B 我不会
opencv基础到进阶
本文为系列文章的第2篇,主要讲解对图像的像素的操作方法。
2.1存取像素值
为了存取矩阵元素,需要指定元素所在的行和列,程序会返回相应的元素。单通道图像返回单个数值,多通道图像,返回的则是一组向量(Vector)。
我们通过分析一段代码来学习这一节的知识点:
void salt(cv::Mat &image,int n){ for(int k = 0;k<n;k++){ int i = rand()%image.cols; int j = rand()%image.rows;
if(image.channel() == 1)//灰度图
image.at<cv::Vec3b>(j,i)=255; if(image.channels() == 3){//彩色 image.at<cv::Vec3b>(j,i)[0] = 255;//设置为白色 Vec3b为一个由三个8位数组成的向量,是一种数据类型,即由三个unsigned char 组成的向量(三元素向量类型) image.at<cv::Vec3b>(j,i)[1] = 255;//彩色图像每个像素由三部分组成:红,绿,蓝通道 image.at<cv::Vec3b>(j.i)[2] = 255; } } }
这里创建了一个函数,他的第一个参数书一张输入图片,该函数会修改此函数,为了达到这个目的,我们需要传使用的参数传递方式。函数的第二个参数是我们想要替换成白的像素点个数。
Mat有很多函数可以获取其初始化的图像的的属性,公有成员变量cols和rows给出了图像的宽和高。成员函数at(int x,int y)可以用来存放图像元素,但需要在编译期知道图像的数据类型,因为cv::Mat可以存放任意数据类型的元素。所以调用at时需要使用以下方式:
image.at<uchar>(j,i) = 255;
调用时需要先打开一个图像;
cv::Mat image = cv::imread("liufeng.jpg"); salt(image,3000); cv::namedWindow("Image"); cv::imshow("image",image);
我们再来看一个实际应用的函数:
void colorReduce(cv::Mat &image, int div = 64){ int nl = image.rows;//行数 int nc = image.cols*image.channels();//每行的像素个数 for(int j=0;j<nl;j++){ uchar* data = image.ptr<uchar>(j);//cv::Mat提供ptr函数可以得到图像任意行的首地址 等效的指针运算:*data++=*data/div*div + div2 for(int i=0;i<nc;i++){//对每行的元素进行数据处理 data[i]= data[i]/div*div+div/2;//公式 } } }
解释一下原理:在一个彩色图像中,图像数据缓冲区中的前三个自己对应图像左上角像素的三个通道值,接下来的三个字节对应第一行的第二个元素,以此类推。opencv默认使用BGR的通道顺序,第一个通道通常是蓝色。一个WxH大小的图像需要WxHx3个uchar构成的内存块。但是,一般会为了提高效率而在每行的末尾添加一些额外像素,这是处理的的特性决定的,如果行的长度是4或8的倍数,芯片就会更加高效的处理图像,因为他们本身的处理器的位数就是4的倍数(8,16,32,64)。
关于公式的解释:注意到data[i]是整数(假设原来是120),x/div得到的是商(1),余数被舍弃,再×div得到的是64,再加上div/2就是64+32=98。推广点我们可以想到64~127之间的数经过上述运算得到的都是98,其他区间的数可以依此类推。这样就起到了压缩色彩空间的作用。
但是上面这个方法的缺点为有两个for循环,效率较低,我们可以改进一下:
void colorReduce(cv::Mat & image,int div =64){ int nl = image.rows; int nc= iamge.cols*image.channels();//每行的像素个数 if(image.isContinuous()){//,没有额外的填补像素 nc = nc*nl; nl = 1;} } for(int j=0;j<nl;j++){//对于连续图像,本循环只执行一次 uchar*data = image.ptr<uchar>(j); for(int i=0;i<nc;i++){ data[i]=data[i]/div*div+div/2;} }
isContinuous函数可以用来判断这幅图像是否进行了填补,为真则没有进行填补。在没有进行填补时我们就将图像视为长度为WxH的一维数组。
reshape函数可以用来转换数组的维数。
if(image.isContinuous){ image.reshape(1,//通道数 reshape不需要内存拷贝或者重新分配就能改变矩阵的维度。连个参数分别为新的通道数和新的行数
image.cols*image.rows);//行数 } int nl = image.rows; int nc = image.cols*image.channels;
2.2使用迭代器遍历图像
迭代器是一种特殊的类,他专门用来遍历集合中的各个元素,同时隐藏了在给定的集合上元素迭代的具体实现方式。标准模板库(STL)为每个容器类提供了迭代器。下划线意味着cv::Mat Iterator_是一个模板类。这样做的原因是因为通过迭代器来存取图像的元素,就必须在编译期知道图像元素的数据类型。
创建迭代器
cv::Mat Iterator_<cv::Vec3b> it;
另一种方法是使用定义在Mat_内部的迭代器类型:
cv::Mat_<cv::Vec3b>::iterator it;
使用第二种方法可以通过常规的begin和end这两个迭代器方法来遍历所有像素:
void colorReduce(cv::Mat &image,int div = 64){ cv::Mat_<cv::Vec3b>::iterator it =image.begin<cv::Vec3b>();//得到起始位置的迭代器 cv::Mat_<cv::Vec3b>::iterator itend =image.begin<cv::Vec3b>();//终止位置迭代器 for(;it!= itend;++it){//处理每个像素 (*it)[0] = (*it)[0]/div[0]*div+div/2; (*it)[1] = (*it)[0]/div[0]*div+div/2; (*it)[2] = (*it)[0]/div[0]*div+div/2; } }
因为我们处理的是彩色图像,所以迭代器返回的是一个向量cv::Vec3b。每个颜色分量可以通过操作符[]得到。
需要的话,对迭代器也可以采取代数运算,如需要把矩阵的第二行作为起始点时可以利用image.begin<cv::Vec3b>()+image.rows来初始化迭代器,使用运算符“*”来读或写元素,读操作:element = *it;写操作:*it = element.
2.3遍历图像与领域操作
在图像处理中,通过当期位置的相邻像素计算新的像素值是很常见的操作(对比等等),当相邻包含图像的前几行和下几行是,你就需要同时扫描图像的若干行。
const uchar* previous = image.ptr<const uchar>(j-1); const uchar* current = image.ptr<const uchar>(j); const uchar* next = image.ptr<const uchar>(j+1);
uchar* output = result.ptr<uchar>(j);//输出行
2.4简单的图像运算
图像是矩阵,矩阵可以代数运算,那么图像当然也可以诺。所有的二元算术函数工作方式都是一样的,他接受两个输入变量和一个输出变量,在一些情况下,还需要指定权重作为运算中的标量因子。每种函数都有几个不同的形式:
//c[i]=a[i]+b[i]; cv::add(imageA,imageB,resultC); //c[i]=a[i]+b[i]; cv::add(imageA.cv::Scalar(k),resultC); //c[i]=k1*a[i]+k2*b[i]+k3; cv::addWeighted(imageA,k1,imageB,k2,k3,resultC); //c[i]=l*a[i]+b[i] cv::sacleAdd(imageA,k,inageB,resultC);
数学运算时常常可能会发生结果超出范围(0~255)的情况发生,这时候我们就可以用cv::saturate_cast来保证结果在范围内。参与运算的图像必须相同的大小和类型,输出图像如果格式不符,那么他会重新分配。
是不是上面的运算特别的复杂,没事,opencv为你做了简化,你可以直接的进行代数运算:
result= 0.7*image1+0.9*image2;
2.5定义感兴趣区域
由于操作运算需要图片具有相同的尺寸,所以我们需要在运算之前定义感兴趣区域(ROI)。需要注意的是ROI和他的父元素指向同一块内存缓冲区。
cv::Mat imageROI; imageROI = image(cv::Rect(110,110,liufeng.cols,liufeng,rows)); cv::addWeighted(imageaROI,1.0,logo,0.3,0.,imageROI);
两张图片合成后可能会出现不协调的情况出现,所以可以将插入出的像素设置为待插入图像的像素值效果会好一点。
imageROI =image(cv::Rect(110,110,liufeng.cols,liufeng.rows));//定义ROI cv::Mat mask= cv::imread("liufeng.bmp",0);//加载掩模 liufeng.copyTo(imageROI,mask);//通过掩模拷贝ROI
利用cv:: rect定义ROI,指定矩形的左上角坐标(前两个参数)和矩形的长宽(后两个参数)就可以定义一个矩形区域了。
另一种方法是使用cv::range来指定感兴趣的行或列的范围:
cv::Mat imageROT= image(cv::Range(110,110+liufeng.rows),cv::range(110,110+liufeng.cols));
如果想创建原始图像特定行或列的ROI,则可以
cv::Mat imageROI = image.rowRange(start,end);
cv::Mat imageROI = image.colRange(start,end);
以上是关于在学习opencv的时候看到多通道矩阵这一概率,恳求大神告诉我一下啥意思的主要内容,如果未能解决你的问题,请参考以下文章