您的位置:首页 > 运维架构

OPENCV2 访问图像像素值的三种方法

2017-09-27 22:18 603 查看
访问图像像素值是图像处理的基本操作。OPENCV2提供了很多中访问方式,本文实现了其中比较常用的三种方式: 
(1) 通过指针访问 

(2) 通过迭代器访问 

(3) 动态地址计算,通过at()函数实现


方法比较: 

(1)用指针访问像素,速度最快;但在彩色图像处理中,如果要单独对某一个颜色分量处理,则需要通过数学公式计算,不是很直观; 

(2)推荐用通过迭代器访问像素,速度快,而且提取BGR某一颜色分量很方便。 

(3)at()函数适用于随机访问某个具体的像素点(已知该像素点行、列坐标),不建议用at()函数遍历整个图。

本文基于以上方法,分别对灰度图和彩色图进行全图遍历,实现图像阈值处理。具体实现代码如下,且在vs2010测试通过。
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"

#include <iostream>
using namespace std;
using namespace cv;

//访问图像像素点,实现阈值处理
void GetGrayImgIntensityByPointer()
{
Mat srcImg, dstImg;
srcImg = imread("D:/openCV/data/naturalImage/data/redComponetImg.jpg", 0);
dstImg = srcImg.clone();//复制,不建议直接对原图处理
int rows = dstImg.rows;
int cols = dstImg.cols * dstImg.channels();
for(int j = 0; j < rows; j++)
{
unsigned char* data = dstImg.ptr(j);//获取每行首地址
for(int i = 0; i < cols; i++)
{
if(data[i] > 190)
data[i] = 255;
else
data[i] = 0;
}
}
imshow("原图像", srcImg);
imshow("阈值处理后图像", dstImg);
waitKey(0);
}

void GetGrayImgIntensityByInterator()
{
Mat srcImg, dstImg;
srcImg = imread("D:/openCV/data/naturalImage/data/redComponetImg.jpg", 0);
dstImg = srcImg.clone();//复制,不建议直接对原图处理
Mat_<uchar>::iterator it = dstImg.begin<uchar>();
Mat_<uchar>::iterator itend = dstImg.end<uchar>();
for(; it != itend; it++)
{
if(*it > 190)
*it = 255;
else
*it = 0;
}
imshow("原图像", srcImg);
imshow("阈值处理后图像", dstImg);
waitKey(0);
}

void GetColorImgIntensityByPointer()
{
Mat srcImg, dstImg;
srcImg = imread("D:/openCV/data/naturalImage/data/opencv.jpg", 1);
dstImg = srcImg.clone();//复制,不建议直接对原图处理
int rows = dstImg.rows;
int cols = dstImg.cols * dstImg.channels();
for(int j = 0; j < rows; j++)
{
unsigned char* data = dstImg.ptr(j);//获取每行首地址
for(int i = 0; i < cols; i++)
{
int ii = i % 2;
if(ii != 0)
data[i] = 0;
else
{
if(data[i] > 190)//对红色分量设置阈值,速度和效果都比不上迭代器
data[i] = 255;
else
data[i] = 0;
}
}
}
imshow("原图像", srcImg);
imshow("阈值处理后图像", dstImg);
waitKey(0);
}

void GetColorImgIntensityByInterator()
{
Mat srcImg, dstImg;
srcImg = imread("D:/openCV/data/naturalImage/data/opencv.jpg", 1);
dstImg = srcImg.clone();//复制,不建议直接对原图处理
Mat_<Vec3b>::iterator it = dstImg.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = dstImg.end<Vec3b>();
for(; it != itend; it++)
{
if((*it)[2] > 190)
{
(*it)[0] = 0;
(*it)[1] = 0;
(*it)[2] = 255;
}

else
{
(*it)[0] = 0;
(*it)[1] = 0;
(*it)[2] = 0;
}
}
imshow("原图像", srcImg);
imshow("阈值处理后图像", dstImg);
waitKey(0);
}

void RandomGetIntensity()//没用到颜色缩减
{
Mat srcImg, dstImg;
srcImg = imread("D:/openCV/data/naturalImage/data/opencv.jpg", 1);
dstImg = srcImg.clone();//复制,不建议直接对原图处理
for(int j = 0; j < dstImg.rows; j++)
for(int i = 0; i < dstImg.cols; i++)
{
if(dstImg.at<Vec3b>(j, i)[2] > 190)
{
dstImg.at<Vec3b>(j, i)[0] = 0;
dstImg.at<Vec3b>(j, i)[1] = 0;
dstImg.at<Vec3b>(j, i)[2] = 255;
}
else
{
dstImg.at<Vec3b>(j, i)[0] = 0;
dstImg.at<Vec3b>(j, i)[1] = 0;
dstImg.at<Vec3b>(j, i)[2] = 0;
}
}
imshow("原图像", srcImg);
imshow("阈值处理后图像", dstImg);
waitKey(0);
}

int main(int argc, char* argv[])
{
//GetGrayImgIntensityByPointer();
GetGrayImgIntensityByInterator();//效果好,速度快
//GetColorImgIntensityByInterator();
//GetColorImgIntensityByPointer();
//RandomGetIntensity();
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

对灰度图阈值处理,效果图如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: