从今天起,开始从头系统学习下opencv,下面记录下图像的基本操作:
1. 图像的读取和显示
Mat image = imread(imagePath, 1);
第二个参数表示图片读入的方式(flags可以缺省,缺省时flags=1,表示以彩色图片方式读入图片)
flags>0时表示以彩色方式读入图片
flags=0时表示以灰度图方式读入图片
flags<0时表示以图片的本来的格式读入图片。
char *f = "E:\\opencv\\sources\\samples\\wp8\\OpenCVXaml\\OpenCVXaml\\Assets\\Lena.png";
Mat lena;
lena = imread(f);
imshow("lena", lena);
- 1
- 2
- 3
- 4
IplImage * lena2;
//lena2 = cvLoadImage(f, CV_LOAD_IMAGE_GRAYSCALE); // 加载灰度图
lena2 = cvLoadImage(f, CV_LOAD_IMAGE_UNCHANGED);//加载原始图像
cvNamedWindow("lena2", CV_WINDOW_AUTOSIZE);//创建窗口
cvShowImage("lena2", lena2);
- 1
- 2
- 3
- 4
- 5
- -
像素读取和操作
1. 利用cv::Mat的at函数,直接访问具体地址
void get_setImagePixel(char *imagePath , int x , int y)
{
// Mat image = imread(imagePath , 0);
Mat image = imread(imagePath, 1);
//得宽高
int w = image.cols;
int h = image.rows;
int channels = image.channels();
if (x < w && y < h)
{
//灰度图,像素为单通道
if (channels == 1)
{
int pixel = image.at<uchar>(x, y);
cout << "灰度图像,处的灰度值为" << pixel << endl;
}
else
{
//通过实验,彩色图像的默认存储是bgr, 且存储的格式如下
//读取
int b = image.at<Vec3b>(x, y)[0]; // b = image.at<uchar>(x,y*3);
cout << b << endl;
int g = image.at<Vec3b>(x, y)[1]; //g = image.at<uchar>(x, y * 3 + 1);
cout << g << endl;
int r = image.at<Vec3b>(x, y)[2]; //r = image.at<uchar>(x, y * 3 + 1);
cout << r << endl;
//设置像素值
image.at<Vec3b>(x, y)[0] = 255;
image.at<Vec3b>(x, y)[1] = 255;
image.at<Vec3b>(x, y)[2] = 255;
}
}
imshow("cc", image);
}
- 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
2. 利用Mat 的prt 函数:行首地址访问
void get_setImagePixel2(char *imagePath, int x, int y)
{
Mat image = imread(imagePath, 1);
//得宽高
int w = image.cols;
int h = image.rows;
int channels = image.channels();
//如果图像连续 ,可以将数据转化为1维数组,提高访问效率,但对少量像素访问就没必要
//if (image.isContinuous())
//{
// //reshape函数用于改变矩阵维度
// //图像行数为1,列数为原先的行数乘上列数
// image.reshape(1, image.cols*image.rows);
//}
//获得第y行的首地址
uchar *data = image.ptr<uchar>(y);
int position = x*channels;
if (channels == 1)
{
int pixel = data[position];
cout << "灰度图像,处的灰度值为" << pixel << endl;
}
else
{
//通过实验,彩色图像的默认存储是bgr, 且存储的格式如下
//读取
int b = data[position];
cout << b << endl;
int g = data[position+1];
cout << g << endl;
int r = data[position+2];
cout << r << endl;
//设置像素值
data[position] = 255;
data[position+1] = 255;
data[position+2] = 255;
}
imshow("cc", image);
}
- 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
3. 利用迭代器遍历图像
void get_setImagePixel3(char *imagePath, int x, int y)
{
Mat image = imread(imagePath, 1);
//得宽高
int w = image.cols;
int h = image.rows;
int channels = image.channels();
if (channels == 1)
{
//得到初始位置的迭代器
Mat_<uchar>::iterator it = image.begin<uchar>();
//得到终止位置的迭代器
Mat_<uchar>::iterator itend = image.end<uchar>();
int pixel = *(it + y * w + x);
cout << "灰度图像,处的灰度值为" << pixel << endl;
}
else
{
//得到初始位置的迭代器
Mat_<Vec3b>::iterator it = image.begin<Vec3b>();
//得到终止位置的迭代器
Mat_<Vec3b>::iterator itend = image.end<Vec3b>();
//读取
it = it + y * w + x;
int b = (*it)[0];
cout << b << endl;
int g = (*it)[1];
cout << g << endl;
int r = (*it)[2];
cout << r << endl;
//设置像素值
(*it)[0] = 255;
(*it)[1] = 255;
(*it)[2] = 255;
}
imshow("cc", image);
}
- 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
若是大量访问数据和更改数据时用第二种方式效率高。
Node: 在修改像素时候,最好先用变量存储,设定好了再赋值给Mat成员对象,如data,因为如果直接进行操作时,当一个分量值大于255时,向前进1的原则,则会修改前面像素的值,如下:
void colorReduce(cv::Mat&image, int div)
{
int nl = image.rows; //图像的行数
//图像每行的像素数
int nc = image.cols * image.channels();
for (int j = 0; j<nl; j++)
{
//得到第j行的首地址
uchar* data = image.ptr<uchar>(j);
//遍历每行的像素
for (int i = 0; i<nc; i++)
{
//printf("%d ", data[i]);
//data[i] = data[i] / div*div + 6;// 这里需要用c来存储,因为如果大于255时会向前进1,则影响前面的像素,data[i] 会自己变得小255
int c = data[i] / div*div + 100;
data[i] = c > 255 ? 255 : c; //将每个像素值都变为div的倍数,即将颜色数缩减了div倍
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20