学习Opencv 2.4.9(二) ---操作像素
作者:咕唧咕唧liukun321
来自:http://blog.csdn.net/liukun321
本质上说一张图像就是由数值组成的矩阵。Opencv 2.x由 cv::Mat 这个数据结构来表示一张图像。矩阵的每个元素代表了一个像素。对于彩色图像而言矩阵的元素是一个三元数。
对图像有了这个新的认识,以下能够试着借助opencv处理图像了。
先来看一下今天要处理的图像:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1a3VuMzIx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
今天的主题是存取像素,首先来看一下怎样存取像素值。事实上对于像素值的操作都能够由cv::Mat类中成员直接或间接实现,cv::Mat有若干成员函数能够获取图像的数据及属性。
操作单个像素方法:
at(int y。 int x)
cv::mat的成员函数: at(int y, int x)能够用来存取图像中相应坐标为(x,y)的元素坐标。
可是在使用它时要注意,在编译期必须要已知图像的数据类型,这是由于cv::mat能够存放随意数据类型的元素。因此at方法的实现是用模板函数来实现的。
用法:假设提前已知一幅图像img的数据类型为 unsigned char型灰度图(单通道),要对坐标为(10,12)的像素又一次赋值为128,则相应操作例如以下:
img.at<uchar>(12,10) = 128;
假设要操作的图片img是一幅数据类型相同为unsigned char的彩色图片,再次要求将坐标(10,12)的像素赋值为128。这个操作跟上面的就有点差别了,须要对这个像素三个通道的每个相应元素赋值,Opencv中图像三原色在内存中的排列顺序为B-G-R(见以下凝视),操作步骤例如以下:
img.at<cv::Vec3b>(12,10) [0]= 128;//B
img.at< cv::Vec3b >(12,10) [1]= 128;//G
img.at< cv::Vec3b >(12,10) [2]= 128;//R
了解了at方法的用法,以下就尝试一下使用at方法对刚才的图片做一个简单的处理(将图像中增加椒盐噪点)。椒盐噪点是一种特殊的噪点,是随机的将图像的部分像素设置为黑色或白色。
既然灰度图与彩色图像对单个元素的操作方式不同,这就须要有一个图像类型推断的过程。
cv::Mat image = cv::imread("test.jpg");
if(image.channles() == 1)
{
//灰度图
}else{
//彩色图
}
清楚了这些过程。以下就来看看增加椒盐噪点函数的实现过程:
#include <opencv2/opencv.hpp>
#include<cstdlib>
using namespace cv; void salt(Mat &img,int saltNum)
{
int x,y;
int i ;
for(i = 0;i < saltNum; i++)
{
x = rand()%img.cols;
y = rand()%img.rows; if(img.channels() == 1)
{
img.at<uchar>(y,x) = 255;
}else if(img.channels() == 3)
{
img.at<Vec3b>(y,x)[0] = 255;
img.at<Vec3b>(y,x)[1] = 255;
img.at<Vec3b>(y,x)[2] = 255;
}
} }
int main()
{
Mat image = imread("../test.jpg"); Mat result;
result = image.clone();
salt(result,3000);
namedWindow("src(http://blog.csdn.net/liukun321)" , CV_WINDOW_AUTOSIZE);
imshow("src(http://blog.csdn.net/liukun321)", image);
imshow("dst(http://blog.csdn.net/liukun321)", result);
waitKey();
return 0;
}
程序执行后的效果图:
原图
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1a3VuMzIx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
增加椒盐噪声后效果
事实上除了at方法操作像素,还能够使用opencv提供的类cv::Mat_ 来实现。
cv::Mat_是一个模板子类。
这个类定义了非常多额外的方法,可是没有提供公共的成员变量。假设已知了矩阵的类型,使用cv::Mat_会带来非常多便利。它的用法例如以下:
cv::Mat_<uchar> img = imread("test.jpg");
img(10,12) = 128;//10行 12列
另一种操作像素的方法:使用Mat类的ptr()方法配合cols 、rows、step、elemSize等成员变量,直接进行指针操作。以下先来说说这几个成员变量
cols代表图像的列数
rows代表图像的高度
step 代表以字节为单位的图像宽度
elemSize 代表像素的大小 (比方一个三通道uchar 型矩阵,返回值为3)
prt()方法相同是个模板类。须要编译期已知像素点的类型:
cv::Mat_<uchar> img = imread("test.jpg");
uchar* addr = img.ptr<uchar>(10);//返回10行的地址
addr +=12;//单通道灰度图
*addr = 128;
相同完毕了对第10行第12列像素的操作。
若图象为三通道彩色图:
cv::Mat_<uchar> img = imread("test.jpg");
uchar* addr = img.ptr<uchar>(10);//返回10行的地址
addr +=12* img.elemSize。//单通道灰度图
*addr = 128;
addr +=12* img.elemSize是由于彩色图象在内存中的存储方式:图像缓冲区中的前三个字节相应图像左上角第一个像素的三个通道值。接下来的三个字节相应第一行的第二个像素。以此类推。
并且注意Opencv默认是使用BGR的通道顺序。
到此已经介绍了3中操作图像中像素的方法。
除这三种以外另一种使用迭代器的操作。今天就不再介绍了。
学习Opencv 2.4.9(二) ---操作像素的更多相关文章
- OpenCV操作像素
在了解了图像的基础知识和OpenCV的基础知识和操作以后,接下来我们要做的就对像素进行操作,我们知道了图像的本质就是一个矩阵,那么一个矩阵中存储了那么多的像素,我们如何来操作呢?下面通过几个例子来看看 ...
- Opencv中图像的遍历与像素操作
Opencv中图像的遍历与像素操作 OpenCV中表示图像的数据结构是cv::Mat,Mat对象本质上是一个由数值组成的矩阵.矩阵的每一个元素代表一个像素,对于灰度图像,像素是由8位无符号数来表示(0 ...
- OpenCV学习笔记(十) 直方图操作
直方图计算 直方图可以统计的不仅仅是颜色灰度, 它可以统计任何图像特征 (如 梯度, 方向等等).直方图的一些具体细节: dims: 需要统计的特征的数目, 在上例中, dims = 1 因为我们仅仅 ...
- OpenCV坐标系与操作像素的四种方法
像素是图像的基本组成单位,熟悉了如何操作像素,就能更好的理解对图像的各种处理变换的实现方式了. 1.at方法 第一种操作像素的方法是使用"at",如一幅3通道的彩色图像image的 ...
- 学习OpenCV研究报告指出系列(二)源代码被编译并配有实例project
下载并安装CMake3.0.1 要自己编译OpenCV2.4.9的源代码.首先.必须下载编译工具,使用的比較多的编译工具是CMake. 以下摘录一段关于CMake的介绍: CMake是一个 ...
- 【学习opencv第六篇】图像的反转操作
考试终于完了,现在终于有时间可以继续学习这个了.写这篇博客主要是因为以前一直搞不清楚图像数据到底是怎么存储的,以及这个step到底是什么,后来查了一下才知道原来step就是数据行的长度.. #incl ...
- 学习OpenCV双目测距原理及常见问题解答
学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化. 图 ...
- <学习opencv>图像和大型阵列类型
OPenCV /*=========================================================================*/ // 图像和大型阵列类型 /* ...
- 【从零学习openCV】IOS7下的人脸检測
前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...
随机推荐
- wcf常用的概念
常见的服务行为包括实例控制.并发控制.元数据发布等 在WCF中,有三种消息交换模式:数据报模式.请求-响应模式.双工模式. 在WCF中一共包含了4种契约,分别是服务契约.数据契约.错误契约和消息契约. ...
- python 使用urllib2下载文件
#! usr/bin/python #coding=utf-8 import urllib2 fp = open('test', 'wb') req = urllib2.urlopen('http:/ ...
- openGL深度缓冲区问题
http://zhidao.baidu.com/question/368299839.html&__bd_tkn__=6aa9196c746cd3357f1eec74aeb127b395029 ...
- 洛谷—— P3908 异或之和
https://www.luogu.org/problemnew/show/P3908 题目描述 求1 \bigoplus 2 \bigoplus\cdots\bigoplus N1⨁2⨁⋯⨁N 的值 ...
- iframe和response.sendRedirect()跳转到父页面的问题
在项目中,因为为了给页面分层次,就使用了 内嵌iframe 的分了三个框.在子页面进行操作的时候,如果session超时,就要被拦截器拦截重新回到首页进行登录,但是在sub页 面 ,进行操作的时候,如 ...
- java.util.Arrays导入报错问题
我的原因:项目jdk的路径没有找到引起的 解决办法:右击项目->Properties->Java build path->Libraries 下错误的jdk,remove,addLi ...
- Android之9图的制作
.9.PNG确实是标准的PNG格式,只是在最外面一圈额外增加1px的边框,这个1px的边框就是用来定义图片中可扩展的和静态不变的区域.特别说明,left和top边框中交叉部分是可拉伸部分,未选中部分是 ...
- c# 中文字符(全角、半角)通用处理
声明:本文仅提供一种编程思路,所提供代码仅供参考,如需使用,请自行完善. 我们在做程序的的时候经常要处理用户输入,作为我们的主要语言中文,经常会出现全角.半角的问题,这会在查询时给我们带来很多麻烦.本 ...
- SpannableString 转换局部字体大小,但在EditText测量之前设置内容,测量高度为,字体变小之前的高度
public void setHint(@NonNull String hint, @Nullable CharSequence subHint) { this.hint = hint; if (su ...
- 设计模式之工厂模式之抽象工厂(php实现)
github地址: git@github.com:ZQCard/design_pattern.git 抽象工厂模式: 先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族.图中 ...