uchar类型
typedef unsigned uint; typedef signed char schar; typedef unsigned char uchar; typedef unsigned short ushort;
Vec系列
Vec+数字+字母: C++STL vector容器类似
数字: Vec 的长度
字母: 类型
b: uchar
s:short
w: ushort
i: int
f:float
d:double
typedef VecVec2b; typedef Vec Vec3b; typedef VecVec4b; typedef Vec Vec2s; typedef Vec Vec3s; typedef Vec Vec4s; typedef Vec Vec2w; typedef Vec Vec3w; typedef Vec Vec4w; typedef Vec Vec2i; typedef Vec Vec3i; typedef Vec Vec4i; typedef Vec Vec6i; typedef Vec Vec8i; typedef Vec Vec2f; typedef Vec Vec3f; typedef Vec Vec4f; typedef Vec Vec6f; typedef Vec Vec2d; typedef Vec Vec3d; typedef Vec Vec4d; typedef Vec Vec6d;
注意:①at方法的使用,是Mat中的模板函数,需要实例化,
(unsigned char---->8个位都是用来存储相关的像素信息),然后传入x,y坐标即可。 其返回值是引用类型,所以才有了下面的负片处理
②Mat中channels()方法获取图片的通道数,是一维的(黑白)还是三维的(rgb)
③注意dims=3的情况,如何接收pixel值的?--->Vec3b类型的容器接收。
- int dims = img.channels(); //得到图片通道数
- for (int i = 0; i < img.rows; i++)
- {
- for (int j = 0; j < img.cols; j++)
- {
- if (dims == 1)
- {
- //单通道图像像素点获取
- int pixel = img.at
(i, j); - img.at
(i, j) = 255 - pixel; //负片处理 - }
- if (dims == 3)
- {
- //三通道图像像素点获取
- Vec3b bgr = img.at
(i, j); - //负片处理
- img.at
(i, j)[0] = 255 - bgr[0]; - img.at
(i, j)[1] = 255 - bgr[1]; - img.at
(i, j)[2] = 255 - bgr[2]; - }
- }
- }
注意:Mat中的成员函数ptr用uchar实例化之后,传入要获取的行数,即可。
- //二维数组-->一级指针访问二维数组方式
- int dims = img.channels();
- for (int i = 0; i < img.rows; i++)
- {
- //Mat中有一个ptr成员函数,获取当前i行的指针
- uchar* current_row = img.ptr
(i); - for (int j = 0; j < img.cols; j++)
- {
- if (dims == 1)
- {
- int pixel = *current_row; //current_row[j];
- *current_row++ = 255 - pixel; //做一个横向移动
- }
- if (dims == 3)
- {
- Vec3b bgr = img.at
(i, j); - *current_row++ = 255 - *current_row;
- *current_row++ = 255 - *current_row;
- *current_row++ = 255 - *current_row;
- }
- }
- }
注意:*p++中*和++的运算优先级相同,自右向左的运算顺序,
所以先++(指针的指向先发生改变)
- #include
- #include
- using namespace cv;
- using namespace std;
- class ImgVisitPixel
- {
- public:
- ImgVisitPixel(int type = IMREAD_UNCHANGED) :img(imread("mm.jpg",type)) {}
- void Show(string wName)
- {
- imshow(wName, img);
- moveWindow(wName, 600, 300);
- waitKey(0);
- }
- void Visit_By_Array();
- void Visit_By_Point();
- protected:
- Mat img;
- };
-
- void ImgVisitPixel::Visit_By_Array()
- {
- int dims = img.channels(); //得到图片通道数
- for (int i = 0; i < img.rows; i++)
- {
- for (int j = 0; j < img.cols; j++)
- {
- if (dims == 1)
- {
- //单通道图像像素点获取
- int pixel = img.at
(i, j); - img.at
(i, j) = 255 - pixel; //负片处理 - }
- if (dims == 3)
- {
- //三通道图像像素点获取
- Vec3b bgr = img.at
(i, j); - //负片处理
- img.at
(i, j)[0] = 255 - bgr[0]; - img.at
(i, j)[1] = 255 - bgr[1]; - img.at
(i, j)[2] = 255 - bgr[2]; - }
- }
- }
- }
-
- void ImgVisitPixel::Visit_By_Point()
- {
- int dims = img.channels();
- for (int i = 0; i < img.rows; i++)
- {
- //Mat中有一个ptr成员函数,获取当前i行的指针
- uchar* current_row = img.ptr
(i); - for (int j = 0; j < img.cols; j++)
- {
- if (dims == 1)
- {
- int pixel = *current_row; //current_row[j];
- *current_row++ = 255 - pixel; //做一个横向移动
- }
- if (dims == 3)
- {
- Vec3b bgr = img.at
(i, j); - *current_row++ = 255 - *current_row;
- *current_row++ = 255 - *current_row;
- *current_row++ = 255 - *current_row;
- }
- }
- }
-
- }
-
- int main()
- {
- ImgVisitPixel* pImg = new ImgVisitPixel;
- pImg->Show("原图");
- pImg->Visit_By_Array();
- pImg->Show("第一次负片操作");
- pImg->Visit_By_Point();
- pImg->Show("第二次负片操作");
- return 0;
- }
在读取到像素点的时候,做一些算数运算,一定要注意颜色范围问题,小心溢出,针对溢出,opencv提供一个转换防止溢出
saturate_cast<要转换的类型>(要转换的数据)
小于0 等于0
大于255 直接等于255
- img.at
(i, j)[0] =saturate_cast(bgr[0]+100); - img.at
(i, j)[1] = saturate_cast(bgr[1] + 100); - img.at
(i, j)[2] = saturate_cast(bgr[2] + 100);
注意:参与算术运算图像的数据类型、通道数目、大小必须相同!!!
- void add(InputArray src1, InputArray src2, OutputArray dst,InputArray mask = noArray(), int dtype = -1);
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * mask: 遮罩像素 可有可无
- * dtype: 输出图深度 可有可无
- *********************************************************************/
- void subtract(InputArray src1,InputArray src2,OutputArray dst,InputArray mask = noArray(),int dtype = -1);
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * mask: 遮罩像素 可有可无
- * dtype: 输出图深度 可有可无
- *********************************************************************/
- void multiply(InputArray src1, InputArray src2,OutputArray dst, double scale = 1, int dtype = -1);
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * scale: 缩放因子,即在src1*src2的基础上再乘scale
- * dtype: 输出图深度 可有可无
- *********************************************************************/
- void divide(InputArray src1, InputArray src2, OutputArray dst,double scale = 1, int dtype = -1);
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * scale: 缩放因子,即在src1*src2的基础上再乘scale
- * dtype: 输出图深度 可有可无
- *********************************************************************/
dst = α · img1 + β · img2 + γ
- void addWeighted(InputArray s1,double a,InputArray s2,double b,double gamma,OutputArray d,int dtype = -1);
- /*******************************************************************
- * s1: 输入图1
- * a: 输入图占比 α
- * s2: 输入图2
- * b: 输入图2占比 β
- * gamma: 附加值,结果基础上再加+gamma γ
- * dst: 输出图
- * dtype: 输出图深度 可有可无
- *********************************************************************/
- #include
- #include
- using namespace cv;
- using namespace std;
- class ImgOpreations
- {
- public:
- ImgOpreations() :img1(imread("mm.jpg")), img2(imread("text.jpg"))
- {
- result = Mat::zeros(img1.size(), img2.type()); //存储的图像一定要初始化
- }
- void testAdd(string wName="Add")
- {
- add(img1, img2, result);
- imshow(wName, result);
- waitKey(0);
- }
- void testSub(string wName="Sub")
- {
- subtract(img1, img2, result);
- imshow(wName, result);
- waitKey(0);
- }
- void testMul(string wName="Mul")
- {
- multiply(img1, img2, result);
- imshow(wName, result);
- waitKey(0);
- }
- void testDivide(string wName = "Div")
- {
- divide(img1, img2, result);
- imshow(wName, result);
- waitKey(0);
- }
- //dst = α · img1 + β · img2 + γ
- void testAddWeighted(string wName = "AddWeighted")
- {
- addWeighted(img1, 0.6, img2, 0.4, 0, result);
- imshow(wName, result);
- waitKey(0);
- }
-
- protected:
- Mat img1;
- Mat img2;
- Mat result;
- };
-
-
- int main()
- {
- ImgOpreations* pImg = new ImgOpreations;
- pImg->testAdd();
- pImg->testSub();
- pImg->testMul();
- pImg->testDivide();
- pImg->testAddWeighted();
- return 0;
- }
- void bitwise_and(InputArray src1, InputArray src2,,OutputArray dst, InputArray mask = noArray());
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * mask: 遮罩像素 可有可无
- *********************************************************************/
- void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray());
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * mask: 遮罩像素 可有可无
- *********************************************************************/
- void bitwise_not(InputArray src, OutputArray dst,InputArray mask = noArray());
- /*******************************************************************
- * src1: 输入图1
- * dst: 输出图
- * mask: 遮罩像素 可有可无
- *********************************************************************/
- void bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask = noArray());
- /*******************************************************************
- * src1: 输入图1
- * src2: 输入图2
- * dst: 输出图
- * mask: 遮罩像素 可有可无
- *********************************************************************/
- #include
- #include
- using namespace cv;
- using namespace std;
- class BitWise
- {
- public:
- BitWise() :img1(imread("mm.jpg")), img2(imread("text.jpg")) {}
- void Show()
- {
- imshow("mm", img1);
- imshow("text", img2);
- }
- void BitOpreations()
- {
- Mat myand, myor, myxor, mynot;
- bitwise_and(img1, img2, myand);
- bitwise_or(img1, img2, myor);
- bitwise_not(img1, mynot);
- bitwise_xor(img1, img2, myxor);
-
- imshow("and", myand);
- imshow("or", myor);
- imshow("xor", myxor);
- imshow("not", mynot);
- waitKey(0);
- }
- protected:
- Mat img1;
- Mat img2;
- };
- int main()
- {
- BitWise* pImg = new BitWise;
- pImg->Show();
- pImg->BitOpreations();
- return 0;
- }
注意:
①函数Scalar的使用,传入一个参数就是单通道,三个参数就是RGB
②注意构造函数的写法,在Mat类型的img中利用Rect函数进行绘制。
- #include
- #include
- using namespace cv;
- using namespace std;
- class BitWise
- {
- public:
- BitWise() :img1(Mat(200,200,CV_8UC1)), img2(Mat(200,200,CV_8UC1))
- {
- //Rect绘制矩形(左上角坐标 和绘制矩形宽度和高度)
- img1(Rect(50, 50, 100, 100)) = Scalar(255);
- img2(Rect(100, 100, 100, 100)) = Scalar(255);
- }
- void Show()
- {
- imshow("mm", img1);
- imshow("text", img2);
- waitKey(0);
- }
- void BitOpreations()
- {
- Mat myand, myor, myxor, mynot;
- bitwise_and(img1, img2, myand);
- bitwise_or(img1, img2, myor);
- bitwise_not(img1, mynot);
- bitwise_xor(img1, img2, myxor);
-
- imshow("and", myand);
- imshow("or", myor);
- imshow("xor", myxor);
- imshow("not", mynot);
- waitKey(0);
- }
- protected:
- Mat img1;
- Mat img2;
- };
- int main()
- {
- BitWise* pImg = new BitWise;
- pImg->Show();
- pImg->BitOpreations();
- return 0;
- }