**
以前一直用MATLAB做图像仿真,这次学习OPENCV后,第一步就是读取图像,并对图像进行位操作,在OPENCV中比较重要和基础的一个数据结构是MAT,针对MAT型结构的位处理,进行了以下试验。
**
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
#include"hessianHead.h"
using namespace cv;
using namespace std;
#define Name1 "图一_3通道_Ptr_8位有符号"
#define Name2 "图二_3通道_At_8位有符号"
#define Name3 "图三_1通道_At_8位无符号"
#define Name4 "图四_对分离后的channel进行操作"
#define Name5 "图五_直接生成channel再进行合并"
int main()
{
Mat emptyImg1(
500,
500,CV_8SC3);
Mat emptyImg2(
500,
500, CV_8SC3);
for (
int i =
0; i < emptyImg1.rows; i++)
{
for (
int b =
0, g =
1, r =
2; r < emptyImg1.rows*
3; b +=
3, g +=
3, r +=
3)
{
emptyImg1.ptr<
char>(i)[b] =
120;
emptyImg1.ptr<
char>(i)[g] = -
127;
emptyImg1.ptr<
char>(i)[r] = -
127;
emptyImg2.at<
char>(i,b) =
120;
emptyImg2.at<
char>(i,g) =
0;
emptyImg2.at<
char>(i,r) =
0;
}
}
namedWindow(Name1, WINDOW_NORMAL);
imshow(Name1, emptyImg1);
namedWindow(Name2, WINDOW_NORMAL);
imshow(Name2, emptyImg2);
Mat emptyImg3(
20,
20, CV_8UC1);
for (
int i =
0; i <
20; i++)
{
for (
int j =
0; j<
20; j++)
{
emptyImg3.at<uchar>(i, j) =
60;
}
}
namedWindow(Name3, WINDOW_NORMAL);
imshow(Name3, emptyImg3);
Mat emptyImg4(
20,
20, CV_8SC3);
Mat megeImg1, megeImg2;
vector<Mat> channels;
vector<Mat> channelsForMege;
Mat imgBlueChannel;
Mat imgGrayChannel;
Mat imgRedChannel;
split(emptyImg4, channels);
channels.at(
0).copyTo(imgBlueChannel);
channels.at(
1).copyTo(imgGrayChannel);
channels.at(
2).copyTo(imgRedChannel);
for (
int i =
0; i <
20; i++)
{
for (
int j =
0; j<
20; j++)
{
channels.at(
0).at<uchar>(i, j) =
0;
channels.at(
1).at<uchar>(i, j) =
100;
channels.at(
2).at<uchar>(i, j) =
100;
imgBlueChannel.at<uchar>(i, j) =
1;
imgGrayChannel.at<uchar>(i, j) =
1;
imgRedChannel.at<uchar>(i, j) =
1;
}
}
channelsForMege.push_back(imgBlueChannel);
channelsForMege.push_back(imgGrayChannel);
channelsForMege.push_back(imgRedChannel);
merge(channelsForMege, megeImg2);
merge(channels, megeImg1);
namedWindow(Name4, WINDOW_NORMAL);
namedWindow(Name5, WINDOW_NORMAL);
imshow(Name4, megeImg1);
imshow(Name5, megeImg2);
Mat emptyImg6(
20,
20, CV_32FC3);
double gr =
228 /
255;
for (
int i =
0; i < emptyImg6.rows; i++)
{
for (
int b =
0, g =
1, r =
2; r < emptyImg6.rows *
3; b +=
3, g +=
3, r +=
3)
{
emptyImg6.ptr<
float>(i)[b] =
0.5;
emptyImg6.ptr<
float>(i)[g] =
0.89;
emptyImg6.ptr<
float>(i)[r] =
0.89;
}
}
cout << gr;
namedWindow(
"six", WINDOW_NORMAL);
imshow(
"six", emptyImg6);
waitKey(
0);
return 0;
}
试验结果图
总结:
1.按位操作,可以用MAT的at和ptr函数来实现,两者的写法不同,对位置位(i,j)处的像素,两者的表示的是at(i,j),ptr(i)[j];
2.彩色图像在OPENCV中的存储通道顺序是B-G-R,对彩色图像进行通道分离,可以利用split(srcImg, channels),这里channels是一个MAT类型的通道向量,可以通过at提取出来;
3.对多个通道合并可以用merge(channels,dstImg)函数,这里这里channels是一个MAT类型的通道向量,并按BGR的顺序在0-2的位置存放对应色彩通道数据,其中,通道向量可以用vector channels创建,并用channels.push_back( )按B-G-R的先后顺序存入;
4.对于1中的type类型,如果图像开始创建的类型为8S/8U,这里type对应着char/uchar,其赋值范围为-127~127/0~255;若初始创建类型为32F,则type类型可用float,赋值范围为0~1,小数点后几位。(此条待进一步修正)