openCV._imread opencv

openCV._imread opencv         近日,开始学习图像处理,思前想后决定以opencv作为实验基础。遂完成图片读取和显示功能。Imread作为常用的图像读取函数,虽然简单,但是参数的选择非常重要,直接影响到后期处理。同时在调试学习过程中也可以学习到图像处理的知识。1.函数原型Matimread(constString&filename,intflags=IMREAD_COLOR)…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

          近日,开始学习图像处理,思前想后决定以opencv作为实验基础。遂完成图片读取和显示功能。Imread作为常用的图像读取函数,虽然简单,但是参数的选择非常重要,直接影响到后期处理。同时在调试学习过程中也可以学习到图像处理的知识。
1. 函数原型

   Mat imread(const String& filename,int flags = IMREAD_COLOR);

    返回Mat对象;

       参数filename: 待打开图片的绝对地址,需要注意的是,并不是所有文件都可以用它打开,它支持的文件如下;函数识别不是依靠文件的后缀名,而是依靠内容的编码格式;

需要注意的是imread读取数据时会重新排列数据。

  •     Windows bitmaps – *.bmp, *.dib (always supported)
  •     JPEG files – *.jpeg, *.jpg, *.jpe (see the Notes section)
  •     JPEG 2000 files – *.jp2 (see the Notes section)
  •     Portable Network Graphics – *.png (see the Notes section)
  •     WebP – *.webp (see the Notes section)
  •     Portable image format – *.pbm, *.pgm, *.ppm *.pxm, *.pnm (always supported)
  •     Sun rasters – *.sr, *.ras (always supported)
  •     TIFF files – *.tiff, *.tif (see the Notes section)
  •     OpenEXR Image files – *.exr (see the Notes section)
  •     Radiance HDR – *.hdr, *.pic (always supported)
  •     Raster and Vector geospatial data supported by Gdal (see the Notes section)

    参数flags:打开的参数,这个非常重要,因为如果设置不合适的话,很容易出现预想之外的效果。它可以指导将原图读取时进行一定的转换。默认值是IMREAD_LOAD_GDAL。因此,如果是想直接处理原图,应该设置为IMREAD_UNCHANED。

openCV._imread opencv

 

2. 通道编码顺序

    通道,与像素深度深度有关。灰度图通常是8比特的像素深度,则通道数为1。如果是彩色图,且为RGB编码,那么一般为24比特的像素深度,通道数为3。而有的彩色图的像素深度是16或者32比特。16比特可能有多种情况:一是压缩的RGB格式,二是YUV的输出。无论何种,都是只有2通道,需要手动解析分离。32比特(windows *.bmp)的像素深度对应的彩色图,则表示的是4通道,RGBA,多出的A表示的是透明度的索引。

    另外读取时需要注意内部像素的编码顺序,这也依赖于imread的flags选项的取值,如果取值决定转成RGB,那么正常的顺序是BGR,排列顺序如下图所示。如果最后imread输出是四通道,多了Alpha通道,那么顺序是RGBA。

    

3, 图像像素通道数据访问

    这部分可以借鉴网上资料,可以分为三种类型。

3.1 动态访问at<typename>(i,j)

    Imread返回的mat类,提供了at模板函数。Image.at<uchar>(i, j);取出i行j列的数据,uchar可以理解为imread返回之后图像的编码类型(如1所述的通道)。如果是三通道,则可以是Vec3b,四通道则是Vec4b。

//CV_LOAD_IMAGE_UNCHANGED如果要取A分量那么flag最好设置成这个值
Mat image = imread("1_firstlai.png", CV_LOAD_IMAGE_UNCHANGED);

for(int i=0;i<image.rows;i++)

{

    for(int j=0;j<image.cols;j++)

    {

        image.at<Vec3b>(i,j)[0]; //B

        image.at<Vec3b>(i,j)[1]; //G

        image.at<Vec3b>(i,j)[2]; //R

       

        image.at<Vec4b>(i,j)[0]; //B

        image.at<Vec4b>(i,j)[1]; //G

        image.at<Vec4b>(i,j)[2]; //R

        image.at<Vec4b>(i,j)[3]; //A

    }

}

 
3.2 指针-更加高效
 

imgage.ptr<uchar>(i)。

int nr=image.rows;

// 将3通道转换为1通道

int nl=image.cols*image.channels();

for(int k=0;k<nr;k++)

{

    // 每一行图像的指针

    const uchar* inData=image.ptr<uchar>(k);

    for(int i=0;i<nl;i++)

    {

        inData[i];

    }

}

    本质就是将每行的3/4通道数据转换为1通道数据访问,因为OpenCV内部存储每一行像素数据以及像素内部通道数据都是连续存储的。但是行与行的数据并不一定是连续存储的,所以不能应用在行与行之间。
3.3 结合isContinuous的指针

    3.2中已经说明了,OpenCV中行与行之间不一定连续存储,也就是有可能连续存储,而且提供了对应的API支持判断是否连续这一现象,也可基于此,再提高访问速度。

int nr=image.rows;

int nc=image.cols*image.channels();

if(image.isContinuous()){

    nc=nc*nr;

    nr=1;

}

for(int i=0;i<nr;i++){

    // 每一行图像的指针

    const uchar* inData=image.ptr<uchar>(i);

    for(int j=0;j<nc;j++){

        inData[j];

    }

}

3.4 安全但低效的迭代器

    3.1-3.3的方法虽然效率高,但是如果操作不小心,容易造成数组越界的Bug。所以opencv提供了一种更安全的访问方法-迭代器。

MatIterator_<Vec3b> it_im, itEnd_im;

it_im    = im.begin<Vec3b>();

itEnd_im = im.end<Vec3b>();

for (; it_im != itEnd_im; it_im++, it_om++){  

    (*it_im)[0] ; //B

    (*it_im)[1] ; //G

    (*it_im)[2] ; //R

}  

———————  
作者:时行居正  
来源:CSDN  
原文:https://blog.csdn.net/firstlai/article/details/70882240  
版权声明:本文为博主原创文章,转载请附上博文链接!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/184192.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 进程调度算法设计_三种调度算法

    进程调度算法设计_三种调度算法【实验目的】进程管理是操作系统中的重要功能,用来创建进程、撤消进程、实现进程状态转换,它提供了在可运行的进程之间复用CPU的方法。在进程管理中,进程调度是核心,因为在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态,当就绪进程个数大于处理器数目时,就必须依照某种策略决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的进程调度,目的是加深对进程调度工作的理解,掌握不…

    2022年9月26日
    4
  • c 获取UUID_c获取程序运行路径

    c 获取UUID_c获取程序运行路径计算机获取UUIDUUID是通用唯一识别码(UniversallyUniqueIdentifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名…

    2022年8月9日
    19
  • Landsat8数据不同波段组合的用途「建议收藏」

    Landsat8数据不同波段组合的用途「建议收藏」2013年2月11日发射的Landsat系列最新卫星Landsat8,携带有OLI陆地成像仪和TIRS热红外传感器,Landsat8的OLI陆地成像仪包括9个波段,OLI包括了ETM+传感器所有的波段,为了避免大气吸收特征,OLI对波段进行了重新调整,比较大的调整是OLIBand5(0.845–0.885μm),排除了0.825μm处水汽吸收特征;OLI全色波段Band8波段范围较窄,这种方式

    2022年7月23日
    12
  • 阿里的笔试题_阿里巴巴java笔试题

    阿里的笔试题_阿里巴巴java笔试题2015阿里笔试题阿里2015招聘实习生笔试题笔试最后一题,题目大意是:给定一数组,数组中每个元素代表一个宽度为1的墙,求由这些墙能装多少水,输入为[1,0,2,1,0,1,3,2,1,2,1],输出为6.时间复杂度为O(n),空间复杂度为O(1).#includeusingnamespacestd;intVolume(intA[],intn){i

    2025年10月10日
    2
  • idea破解教程2019.3(idea旗舰版如何破解)

    我自己在网上看半天找出来的,主要是破解补丁不知道怎么对应,第一步:下载安装包与破解补丁:安装包:链接:https://pan.baidu.com/s/1Ohy-cp-wrwb1YLelD3DLZA提取码:czdf破解补丁:链接:https://pan.baidu.com/s/1bj2EHJ_BAcfN6IZHQKAh_Q提取码:v3vr第二步:修改idea文件将破解补丁放到…

    2022年4月17日
    97
  • ip addr命令配置ip_linux查不到ip地址

    ip addr命令配置ip_linux查不到ip地址在高可用,多线路及系统维护的特殊情况下,我们通常会通过”ipaddr”这一命令来添加一个隐形IP在相应的设备上,但是当我们在一个设备上添加多个ip的时候,删除某个IP的时候尤其要注意,下面通过几个实例来说明,如下root@localhost~]#ipaddradd10.1.1.230/24deveth0[root@localhost~]#ipaddradd10….

    2022年7月27日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号