图像常用的基本元素的表达:(参考Opencv入门教程)
对于单通道图像,其元素类型一般为 8U(即8 位无符号整数),当然也可以是16S、32F 等;这些类型可以直接用 uchar、short、float 等C/C++语言中的基本。
对于BGR图像,OpenCV 中有模板类 Vec,可以表示一个向量。OpenCV 中使用Vec类预定义了一些小向量,可以将之用于矩阵元素的表达。
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;
typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;
typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;
typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
例如 8U类型的 RGB彩色图像可以使用 Vec3b,3 通道float 类型的矩阵可以使用Vec3f。
对于 Vec对象,可以使用[]符号如操作数组般读写其元素,如:
Vec3b color; //用color 变量描述一种 RGB颜色
color[0]=255; //B分量
color[1]=0; //G分量
color[2]=0; //R分量
所以我们可以通过以下方式来翻转BGR图像:
bool fanzhuan(Mat image,int flag)
{
Mat dst=image.clone();
int rows=dst.rows,i;
int cols=dst.cols,j;
for(i=1;i<rows;i++)
for(j=1;j<cols;j++)
{
if(flag==1)//水平翻转
dst.at<Vec3b>(i,j)=image.at<Vec3b>(i,cols-j-1);
else if(flag==0)//竖直翻转
dst.at<Vec3b>(i,j)=image.at<Vec3b>(rows-i-1,j);
else//水平竖直翻转
{
dst.at<Vec3b>(i,j)=image.at<Vec3b>(rows-i-1,cols-j-1);
}
}
imshow("2",dst);
waitKey(0);
return 1;
}
int main()
{
Mat src;
src=imread("lena.jpg");
if(!src.data)
{cout<<"read src error!";return -1;}
imshow("1",src);
if(fanzhuan(src,0))
cout<<"图像翻转成功"<<endl;
/*flip(src,src,1);//正值水平变换,0垂直变换,负值二者都有
imshow("2",src);
waitKey(0);*/
return 0;
}
今天看到了另一种随机数 函数RNG
int main()
{
int i,j;
uchar b[10][10];//**找到了先前随机数组很多为0的原因,这数组的类型不能是int型的,这里unchar b[100]和uchar b[10][10]效果一样**
RNG rng;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
{
b[i][j]=rng.uniform(0,256);
//cout<<b[i][j];
}
cout<<"\n";
Mat M(10,10,CV_8UC1,b);
Mat N,L;
blur(M, N,Size(3, 3)); //均值滤波
medianBlur(M,L,3);//中值滤波
if(salt(M,10))
cout<<M<<endl;
cout<<N<<endl;
cout<<L<<endl;
waitKey(0);
return 0;
}