详解OpenCV图像的概念和基本操作

前言:

opencv最主要的的功能是用于图像处理,所以图像的概念贯穿了整个opencv,与其相关的核心类就是Mat。

像素:

图片尺寸以像素为单位时,每一厘米等于28像素,如1515厘米长度的图片,等于420420像素的长度。一个像素所能表达的不同颜色数取决于比特每像素(BPP)。

灰度图像:8bpp=2的8次方=256色,
高彩色:16bpp=2的16次方=65536色,
真彩色:24bpps=2的24次方=16777216色。

图像分辨率:

图像分辨率是图像总像素的多少,由于图像通常用矩阵表示,所以分辨率常用,mn表示,注意: n 表示行数(代表一列包含的像素),m表示列数代表一行包含的像素。

640X480表示图像的长和宽分别为640和480,总像素为640X480=307200(相机中所说的30万分辨率),
800X600表示图像的长和宽分别为800和600,总像素为800X600=480000(相机中所说的50万分辨率)。

图像和矩阵

图像是由像素组成的,而像素实际上就是带有坐标位置和颜色信息的点。我们把图片想象成由若干行,若干列的点组成的, 现实中有RGB颜色系统,我们可以把图中任意一点(位置在第m行,第n列)的点A表示为

A[m,n] = [blue,green,red]
参数解读
m |A点在图像中的第m行
n |A点在图像中的第n列
blue |表示蓝色,三原色(RGB)的第一个数值
green|表示绿色,三原色(RGB)的第二个数值
red |表示红色,三原色(RGB)的第一个数值

每个点对应的亮度可以理解为rgb的值,无符号8位数3维,则一个像素点为3维数组,分别对应RGB的值,在OpenCV中数据类型为:cV_8u3C。
假设Mx N,lij表示第j行j列,对应上图就是M= 300,N= 200。
假设Mx N,lij表示第j行j列,对应上图就是M= 300,N= 200。

注意:在Opencv中三维数组存储RGB值,存储颜色通道的顺序不是RGB,而是BGR,如下图:

Mat排列方式如下:

像素值的读写

很多时候,我们需要读取某个像素值,或者设置某个像素值;在更多的时候,我们需要对整个图像里的所有像素进行遍历。OpenCV提供了多种方法来实现图像的遍历。
方法一:at 函数

     cv::Mat grayim(600, 800, CV_8UC1);
    // 遍历所有像素,并设置像素值
    for( int i = 0; i < grayim.rows; ++i)
    {
        for( int j = 0; j < grayim.cols; ++j )
        {
             grayim.at<uchar>(i,j) = (i+j)%255;
        }

    }
   imshow("grayim",grayim);
    cv::Mat colorim(600, 800, CV_8UC3);
    // 遍历所有像素,并设置像素值
    for( int i = 0; i < colorim.rows; ++i)
    {
        for( int j = 0; j < colorim.cols; ++j )
        {
            cv::Vec3b pixel;
            // 注意:opencv通道顺序,BGR,非RGB
            pixel[0] = i%255;  // Blue
            pixel[1] = j%255;  // Green
            pixel[2] = 0;      // Red
            colorim.at<Vec3b>(i,j) = pixel;
        }
    }
    imshow("colorim",colorim);
    waitKey();

方法一:使用数据指针

 cv::Mat grayim(600, 800, CV_8UC1);
    cv::Mat colorim(600, 800, CV_8UC3);
    //遍历所有像素,并设置像素值
    for( int i = 0; i < grayim.rows; ++i)
    {
        //获取第 i 行首像素指针
        uchar * p = grayim.ptr<uchar>(i);
        //对第 i 行的每个像素(byte)操作
        for( int j = 0; j < grayim.cols; ++j )
        p[j] = (i+j)%255;
    }
    //遍历所有像素,并设置像素值
    for( int i = 0; i < colorim.rows; ++i)
    {
        //获取第 i 行首像素指针
        cv::Vec3b * p = colorim.ptr<cv::Vec3b>(i);
        for( int j = 0; j < colorim.cols; ++j )
        {
            p[j][0] = i%255;    //Blue
            p[j][1] = j%255;    //Green
            p[j][2] = 0;        //Red
        }
    }

    imshow("grayim",grayim);
     imshow("colorim",colorim);

实验效果

图像局部操作

选择单行/单列
示例:A矩阵的第i行,将这一行的所有元素都乘以2,然后赋值给第j行

A.row(j)= A.row(i)*2;

选择多行/多列
Range是OpencV中新增的类,该类有两个关键变量star和end。Range对象可以用来表示矩阵的多个连续的行或者多个连续的列。其表示的范围为从start到end,包含start。

// 创建一个单位阵
Mat A = Mat::eye(10, 10, CV_32S);
// 提取第 1 到 3 列(不包括 3)
Mat B = A(Range::all(), Range(1, 3));
// 提取B的第 5 至 9 行(不包括 9)
// 其实等价于C = A(Range(5, 9), Range(1, 3))
Mat C = B(Range(5, 9), Range::all());

选择指定区域

图像中提取感兴趣区域(Region of interest)有两种方法:
方法—:使用构造函数

//创建宽度为 320,高度为 240 的 3 通道图像
Mat img(Size(320, 240), CV_8UC3);
//roi 是表示 img 中 Rect(10, 10, 100, 100)区域的对象
Mat roi(img, Rect(10, 10, 100, 100));

方法二:使用括号运算符

Mat roi2 = img(Rect(10, 10, 100, 100));
//当然也可以使用Range对象来定义感兴趣区域,如下:
// 用括号运算符
Mat roi3 = img(Range(10, 100), Range(10, 100));
// 用构造函数
Mat roi4(img, Range(10, 100), Range(10, 100));

取对角线元素

矩阵的对角线元素可以使用cv::Mat就的diag()函数获取:

Mat Mat::diag(int d) const

1.当d=0时,表示取主对角线; 当参数d>0是,表示取主对角线下方的次对线,
2. 当d=1时,表示取主对角线下方,且紧贴主多角线的元素;
3. 当参数d<0时,示取主对角线上方的次对角线。如同row()和col)函数,diag()函数也不进行内存复制操作,其复杂度也是0(1)。

到此这篇关于OpenCV图像的概念和基本操作的文章就介绍到这了,更多相关OpenCV图像基本操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python+opencv图像分割实现分割不规则ROI区域方法汇总

    在图像分割领域,一个重要任务便是分割出感兴趣(ROI)区域.如果是简易的矩形ROI区域其实是非常容易分割的,opencv的官方python教程里也有教到最简易的矩形ROI分割(剪裁),其本质是多维数组(矩阵)的切片.但是现实情况中,ROI是不规则的多边形,也可能是曲线边界,那么该如何分割出来呢?下面总结几种思路. 可能只提供核心部分的代码示例,具体应用要结合你自己的项目来修正. 一.已知边界坐标,直接画出多边形 例:最基础的画个四边形 # 定义四个顶点坐标 pts = np.array([[10

  • 深入探讨opencv图像矫正算法实战

    摘要 在机器视觉中,对于图像的处理有时候因为放置的原因导致ROI区域倾斜,这个时候我们会想办法把它纠正为正确的角度视角来,方便下一步的布局分析与文字识别,这个时候通过透视变换就可以取得比较好的裁剪效果. 本次实战,对于图像的矫正使用了两种矫正思路: 针对边缘比较明显的图像,使用基于轮廓提取的矫正算法. 针对边缘不明显,但是排列整齐的文本图像,使用了基于霍夫直线探测的矫正算法. 基于轮廓提取的矫正算法 整体思路: 图片灰度化,二值化 检测轮廓,并筛选出目标轮廓(通过横纵比或面积去除干扰轮廓) 获取

  • Python OpenCV 图像区域轮廓标记(框选各种小纸条)

    学在前面 上篇 OpenCV 博客原计划完成一个 识别银行卡号的项目,但是写的过程中发现,技术储备不足,我无法在下述图片中,提取出卡号区域,也就无法进行后续的识别了,再次意识到了自己技术还不达标,继续学习.完不成,就实现其它学习项目. 轮廓识别实战 先看一下最终实现的效果,针对一张图片(该图片前景色和背景色差异较大),进行轮廓标记. 图片基本处理 import cv2 as cv src = cv.imread("./demo.jpg") gray = cv.cvtColor(src,

  • Opencv图像处理之详解掩膜mask

    1.在OpenCV中我们经常会遇到一个名字:Mask(掩膜).很多函数都使用到它,那么这个Mask到底什么呢? 2.如果我们想要裁剪图像中任意形状的区域时,应该怎么办呢? 答案是,使用掩膜(masking). 我们先看一下掩膜的基础.图像的位运算. 图像基本运算 图像的基本运算有很多种,比如两幅图像可以相加.相减.相乘.相除.位运算.平方根.对数.绝对值等:图像也可以放大.缩小.旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作,各个颜色通道还可以分别提取及对各个颜色通道进行各种运算操

  • Python OpenCV 基于图像边缘提取的轮廓发现函数

    基础知识铺垫 在图像中,轮廓可以简单的理解为连接具有相同颜色的所有连续点(边界)的曲线,轮廓可用于形状分析和对象检测.识别等领域. 轮廓发现的原理:先通过阈值分割提取目标物体,再通过边缘检测提取目标物体轮廓. 一个轮廓就是一系列的点(像素),这些点构成了一个有序的点集合. 使用 cv2.findContours 函数可以用来检测图像的边缘. 函数原型说明 contours, hierarchy = cv2.findContours(image, mode, method[, contours[,

  • 详解OpenCV图像的概念和基本操作

    前言: opencv最主要的的功能是用于图像处理,所以图像的概念贯穿了整个opencv,与其相关的核心类就是Mat. 像素: 图片尺寸以像素为单位时,每一厘米等于28像素,如1515厘米长度的图片,等于420420像素的长度.一个像素所能表达的不同颜色数取决于比特每像素(BPP). 灰度图像:8bpp=2的8次方=256色, 高彩色:16bpp=2的16次方=65536色, 真彩色:24bpps=2的24次方=16777216色. 图像分辨率: 图像分辨率是图像总像素的多少,由于图像通常用矩阵表

  • 详解OpenCV自适应直方图均衡化的应用

    目录 介绍 主要代码 比较 CLAHE 和直方图均衡化 介绍 在<直方图均衡化详解>中,我们已经了解的直方图均衡化的基本概念,并且可以使用 cv2.equalizeHist() 函数执行直方图均衡. 在本节中,将介绍如何应用对比度受限的自适应直方图均衡化 ( Contrast Limited Adaptive Histogram Equalization, CLAHE ) 来均衡图像,CLAHE 是自适应直方图均衡化( Adaptive Histogram Equalization, AHE

  • 详解OpenCV实现特征提取的方法

    目录 前言 1. 颜色 2. 形状 3. 纹理 a. GLCM b.  LBP 结论 前言 如何从图像中提取特征?第一次听说“特征提取”一词是在 YouTube 上的机器学习视频教程中,它清楚地解释了我们如何在大型数据集中提取特征. 很简单,数据集的列就是特征.然而,当我遇到计算机视觉主题时,当听说我们将从图像中提取特征时,吃了一惊.是否开始浏览图像的每一列并取出每个像素? 一段时间后,明白了特征提取在计算机视觉中的含义.特征提取是降维过程的一部分,其中,原始数据的初始集被划分并减少到更易于管理

  • 详解OpenCV和PIL读取和显示图像的差异

    本博客演示使用OpenCV和PIL读取和显示图像的差异. 首先来看一下原始的bgr图像 src.jpg 1. 使用cv2读取src.jpg并转为rgb格式的src_rgb.jpg并显示和保存 #首先读入并保存为rgb图像 src_path = 'C:\\Users\\Administrator\\Desktop\\cv2_PIL\\src.png' # bgr img = cv2.imread(src_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB

  • 详解OpenCV中简单的鼠标事件处理

    目录 cv2.setMouseCallback函数语法 回调函数 谈及鼠标事件,就是在触发鼠标按钮后程序所做出相应的反应,但是不影响程序的整个线程.这有些像异步处理.鼠标事件响应不会一直等着我们去按而后续程序不执行,这样会造成阻塞,而是在我们不按鼠标的时候程序也会正常进行,按的时候会调用鼠标的事件响应,这个过程就像程序一边正常运行一边等待鼠标响应. 为了将鼠标响应和操作画面进行绑定,我们要创建一个回调函数: cv2.setMouseCallback函数语法 cv2.setMouseCallbac

  • 详解Python图像形态学处理(开运算,闭运算,梯度运算)

    目录 一.图像开运算 二.图像闭运算 三.图像梯度运算 四.总结 这篇文章将继续介绍开运算.闭运算和梯度运算.数学形态学(Mathematical Morphology)是一种应用于图像处理和模式识别领域的新方法.数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具,其基本思想是用具有一定形态的结构元素去量度和提取图像中对应形状以达到对图像分析和识别的目的. 一.图像开运算 开运算一般能平滑图像的轮廓,削弱狭窄部分,去掉较细的突出.闭运算也是平滑图像的轮廓,与开运算相反,它一般熔合

  • 详解OpenCV执行连通分量标记的方法和分析

    目录 1.OpenCV 连通分量标记和分析 1.1 OpenCV 连通分量标记和分析函数 1.2 项目结构 2.案例实现 2.1 使用 OpenCV 实现基本的连通分量标记 2.2 完整代码 2.3 过滤连通分量 2.4 C++代码案例 在本教程中,您将学习如何使用 OpenCV 执行连通分量标记和分析.具体来说,我们将重点介绍 OpenCV 最常用的连通分量标记函数:cv2.connectedComponentsWithStats. 连通分量标记(也称为连通分量分析.斑点提取或区域标记)是图论

  • 详解opencv去除背景算法的方法比较

    目录 背景减除法 (1)BackgroundSubtractorMOG (2)BackgroundSubtractorMOG2 (3)BackgroundSubtractorGMG 帧差法 最近做opencv项目时,使用肤色分割的方法检测目标物体时,背景带来的干扰非常让人头痛.于是先将背景分割出去,将影响降低甚至消除.由于初次接触opencv,叙述不当的地方还请指正. 背景减除法 (以下文字原文来源于https://docs.opencv.org/3.4.7/d8/d38/tutorial_bg

  • 一文详解cornerstone Tools 基础概念

    目录 cornerstone Tools 基础概念 工具类型 Base Tool BaseAnnotationTool 工具模式 事件 全局配置项 cornerstone Tools 基础概念 Cornerstone Tools 是一个 JavaScript 库,用于帮助注释.分割和测量医学图像.该库还提供了一个框架,用于创建新工具,以一致.连贯的方式管理所有工具,以及导入/导出工具度量数据. 下面将介绍 Cornerstone Tools 中的基本概念,以便后续了解 Cornerstone T

  • 详解OpenCV For Java环境搭建与功能演示

    OpenCV概述 OpenCV做为功能强大的计算机视觉开源框架,包含了500多个算法实现,而且还在不断增加,其最新版本已经更新到3.2.其SDK支持Android与Java平台开发,对于常见的图像处理需求几乎都可以满足,理应成为广大Java与Android程序员的首先的图像处理框架.Java中使用OpenCV的配置及其简单,可以毫不客气的说几乎是零配置都可以. 一:配置 配置引入OpenCV相关jar包,首先要下载OpenCV的自解压版本,下载地址: http://opencv.org/open

随机推荐