2.10、图像像素的逻辑操作
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::bitwise_demo(Mat &image) { Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3); Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3); //rectangle()函数第四个参数小于0表示填充,大于0表示绘制 //rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), 2, LINE_8, 0); //rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), 2, LINE_8, 0); rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0); rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0); imshow("m1", m1); imshow("m2", m2); Mat dst; //bitwise_and(m1, m2, dst); //bitwise_or(m1, m2, dst); //dst = ~image; //也可以实现图像取反操作 //bitwise_not(image, dst); //当前图像取反操作 bitwise_xor(m1, m2, dst); //异或((非m1 与 m2) 或 (m1 与 非m2)),相当于 m1或m2,相交的部分(非(m1 与 m2)) imshow("像素位操作", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/lena.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.bitwise_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.11、通道分离与合并
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::channels_demo(Mat &image) { std::vector<Mat> mv; //Mat数组 split(image, mv); imshow("蓝色", mv[0]); imshow("绿色", mv[1]); imshow("红色", mv[2]); Mat dst; //mv[1] = 0; //mv[2] = 0; //merge(mv, dst); //imshow("蓝色", dst); //mv[0] = 0; //mv[2] = 0; //merge(mv, dst); //imshow("绿色", dst); mv[0] = 0; mv[1] = 0; merge(mv, dst); imshow("红色", dst); //from_to[]复制列表 int from_to[] = { 0,2,1,1,2,0 }; //通道0复制到通道2,通道1复制到通道1,通道2复制到通道0 //mixChannels(输入矩阵,输入矩阵数量,输出矩阵,输出矩阵数量,复制列表,复制列表中复制几次) mixChannels(&image, 1, &dst, 1, from_to, 3); imshow("通道混合", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/flower.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.channels_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.12、图像色彩空间转换
HSV颜色空间表
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::inrange_demo(Mat &image) { Mat hsv; cvtColor(image, hsv, COLOR_BGR2HSV); Mat mask; inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask); imshow("mask01", mask); Mat redback = Mat::zeros(image.size(), image.type()); redback = Scalar(40, 40, 200); bitwise_not(mask, mask); //像素逻辑运算,mask取反 imshow("mask02", mask); //image.copyTo(拷贝到的图像,mask为1的部分拷贝为0的部分不拷贝) image.copyTo(redback, mask); //将image拷贝到其他图像中 imshow("roi区域提取", redback); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.inrange_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.13、图像像素值统计
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::pixel_statistic_demo(Mat &image) { double minv, maxv; Point minLoc, maxLoc; Mat mean, stddev; std::vector<Mat> mv; split(image, mv); for (int i = 0; i < mv.size(); i++) { //第一个参数需要是单通道的图像,可以先把多通道分离;最后一个参数为mask minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat()); std::cout << "No.channels: " << i << " min value: " << minv << " max value: " << maxv << std::endl; //第一个参数是单通道图像则计算一组均值、方差,如果是多通道图像,则同时计算多组均值、方差 meanStdDev(mv[i], mean, stddev); std::cout << "means: " << mean << std::endl; std::cout << "stddev: " << stddev << std::endl; } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.pixel_statistic_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.14、图像几何形状绘制,随机数与随机颜色
基本绘图
1 Point: 2 Point pt; 3 pt.x = 10; 4 pt.y = 8; 5 或者 6 Point pt = Point(10, 8); 7 8 Scalar: 9 Scalar( B, G, R ) //定义的RGB颜色值为:Blue,Green, Red 10 11 line 绘直线: 12 line( img, //输出图像 13 start, //起始点 14 end, //结束点 15 Scalar( 0, 0, 0 ), //颜色 16 thickness=2, //线条粗细 17 lineType=8 ); //线条类型 18 19 ellipse 绘椭圆: 20 ellipse( img, //输出图像 21 Point( w/2.0, w/2.0 ), //中心为点 (w/2.0, w/2.0) 22 Size( w/4.0, w/16.0 ), //大小位于矩形 (w/4.0, w/16.0) 内 23 angle, //旋转角度为 angle 24 0, 25 360, //扩展的弧度从 0 度到 360 度 26 Scalar( 255, 0, 0 ), //颜色 27 thickness, //线条粗细 28 lineType ); //线条类型 29 30 circle 绘圆: 31 circle( img, //输出图像 32 center, //圆心由点 center 定义 33 w/32.0, /圆的半径为: w/32.0 34 Scalar( 0, 0, 255 ), //颜色 35 thickness, //线条粗细 36 lineType ); //线条类型 37 38 rectangle 绘矩形: 39 rectangle( rook_image, 40 Point( 0, 7*w/8.0 ), 41 Point( w, w), //矩形两个对角顶点为 Point( 0, 7*w/8.0 ) 和 Point( w, w) 42 Scalar( 0, 255, 255 ), 43 thickness = -1, 44 lineType = 8 ); 45 46 fillPoly 绘填充的多边形: 47 fillPoly( img, 48 ppt, //多边形的顶点集为 ppt 49 npt, //要绘制的多边形顶点数目为 npt 50 1, //要绘制的多边形数量仅为 1 51 Scalar( 255, 255, 255 ), 52 lineType );
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); };
quickdemo.cpp
void QuickDemo::form_paint_random() { Mat image_line = Mat::zeros(512, 512, CV_8UC3); //新建两个512*512的三通道矩阵 Mat image_rect = Mat::zeros(512, 512, CV_8UC3); Rect rect; //新建一个矩形对象 RNG rng(0xFFFFFF); //生成随机数的类RNG,随机数产生器,用数值0xFFFFFF来实例化一个RNG对象 image_line.setTo(Scalar(0, 0, 0)); //将图像使用另一种颜色覆盖 image_rect.setTo(Scalar(0, 0, 0)); //将图像使用另一种颜色覆盖 for (int i = 0; i < 100000; i++) { int x1 = rng.uniform(0, 512); //获取[0,512)的均匀分布的随机数 int y1 = rng.uniform(0, 512); int x2 = rng.uniform(0, 512); int y2 = rng.uniform(0, 512); int b = rng.uniform(0, 256); int g = rng.uniform(0, 256); int r = rng.uniform(0, 256); //void line(绘制线段的图像,起点坐标,终点坐标,线段的颜色通过Scalar()定义,线段的宽度(线宽为负数时表示填充),线段的类型,坐标点小数点位数) line(image_line, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 1, LINE_AA, 0); //线段的类型。可以取值LINE_8,LINE_4和LINE_AA,分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用LINE_AA(采用了高斯滤波)。 imshow("image_line", image_line); rect.x = x1; //定义矩形的左上顶点坐标及宽高 rect.y = y1; rect.width = x2 - x1; rect.height = y2 - y1; rectangle(image_rect, rect, Scalar(b, g, r), 1, LINE_AA, 0); imshow("image_rect", image_rect); char c = waitKey(20); if (c == 27) break; } }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.form_paint_random(); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.15、多边形填充与绘制
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); };
quickdemo.cpp
void QuickDemo::polyline_drawing_demo() { Mat canvas01 = Mat::zeros(Size(512, 512), CV_8UC3); Mat canvas02 = Mat::zeros(Size(512, 512), CV_8UC3); Point p1(100, 100); Point p2(350, 100); Point p3(450, 280); Point p4(320, 450); Point p5(80, 400); std::vector<Point> pts; pts.push_back(p1); pts.push_back(p2); pts.push_back(p3); pts.push_back(p4); pts.push_back(p5); fillPoly(canvas01, pts, Scalar(255, 255, 0), 8, 0); //polylines(绘制所在图像,要绘制的顶点集合,图形是否闭合,线的颜色,线宽,线的类型) //polylines(canvas, pts, true, Scalar(0, 0, 255), 3, LINE_8, 0); //不能设置线宽为负数进行填充 polylines(canvas01, pts, true, Scalar(0, 0, 255), 3, LINE_AA, 0); //使用LINE_AA抗锯齿 std::vector<std::vector<Point>> contours; contours.push_back(pts); //drawContours(绘制所在的图像,绘制的点集的集合,绘制第几个点集-1表示全部绘制,线段颜色,线宽-1表示填充) drawContours(canvas02, contours, -1, Scalar(255, 0, 0), -1); imshow("多边形绘制01", canvas01); imshow("多边形绘制02", canvas02); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.polyline_drawing_demo(); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.16、鼠标操作与响应
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); };
quickdemo.cpp
Point sp(-1, -1); //起点 Point ep(-1, -1); //终点 //新建一个temp矩阵保存原图像,没有绘制的 Mat temp; static void on_draw(int event, int x, int y, int flags, void *userdata) { Mat image = *((Mat*)userdata); if (event == EVENT_LBUTTONDOWN) { sp.x = x; sp.y = y; std::cout << "start point: " << sp << std::endl; } else if (event == EVENT_LBUTTONUP) { ep.x = x; ep.y = y; int dx = ep.x - sp.x; int dy = ep.y - sp.y; if (dx > 0 && dy > 0) { Rect box(sp.x, sp.y, dx, dy); temp.copyTo(image); //去除绘制目标区域的边框 imshow("ROI区域", image(box)); //将绘制区域中的图像单独显示出来 rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0); imshow("鼠标绘制", image); //ready for next drawing sp.x = -1; sp.y = -1; } } else if (event == EVENT_MOUSEMOVE) { if (sp.x > 0 && sp.y > 0) { ep.x = x; ep.y = y; int dx = ep.x - sp.x; int dy = ep.y - sp.y; if (dx > 0 && dy > 0) { Rect box(sp.x, sp.y, dx, dy); temp.copyTo(image); //每次都重新加载没有绘制的原图,实现擦除过程中绘制的图形 rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0); imshow("鼠标绘制", image); } } } } void QuickDemo::mouse_drawing_demo(Mat &image) { namedWindow("鼠标绘制", WINDOW_AUTOSIZE); setMouseCallback("鼠标绘制", on_draw, (void*)(&image)); imshow("鼠标绘制", image); temp = image.clone(); //将加载的原图克隆到临时矩阵temp中 }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 //imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.mouse_drawing_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.17、图像像素类型转换与归一化
图像为什么要进行归一化:
归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保证程序运行时收敛加快。归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间是统计的概率分布,归一化在某个区间上是统计的坐标分布。归一化有同一、统一和合一的意思。
归一化的目的简而言之,是使得没有可比性的数据变得具有可比性,同时又保持相比较的两个数据之间的相对关系,如大小关系;或是为了作图,原来很难在一张图上作出来,归一化后就可以很方便的给出图上的相对位置等。
四种归一化方式:
其中的NORM_L2计算方式实例如下公式,其他归一化方式根据图片中的内容即可理解
2.0÷22+82+102−−−−−−−−−−−√≈0.152.0÷22+82+102≈0.15
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); };
quickdemo.cpp
//image.type()返回的数值与类型对应关系,第一行为通道数,第一列为数据类型 +--------+----+----+----+----+------+------+------+------+ | | C1 | C2 | C3 | C4 | C(5) | C(6) | C(7) | C(8) | +--------+----+----+----+----+------+------+------+------+ | CV_8U | 0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 | | CV_8S | 1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 | | CV_16U | 2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 | | CV_16S | 3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 | | CV_32S | 4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 | | CV_32F | 5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 | | CV_64F | 6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 | +--------+----+----+----+----+------+------+------+------+ void QuickDemo::norm_demo(Mat &image) { Mat dst; std::cout << image.type() << std::endl; image.convertTo(image, CV_32F); //将8UC3 Integer数据转换成32F float数据,以便用于后续归一化操作 std::cout << image.type() << std::endl; //值归一化与范围归一化:值归一化L1,L2,MINMAX;范围归一化可以自己设置归一化范围如[0,255] //normalize(输入数组,输出数组,1用来规范值2规范范围下限,0值归一化其他范围归一化上限,归一化选择的数学公式类型) normalize(image, dst, 1.0, 0, NORM_MINMAX); //转换为浮点数类型后必须进行归一化操作 std::cout << dst.type() << std::endl; imshow("图像数据归一化前", image); imshow("图像数据归一化后", dst); //CV_8UC3, CV_32FC3 }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.norm_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.18、图像放缩与插值
OpenCV图像放缩的五种插值算法:最近邻、双线性、双三次、基于像素区域关系、兰索斯插值。
1、最近邻:选取离目标点最近的点作为新的插入点;
2、双线性:由相邻的四像素(2 * 2)计算得出;
- 原理公式及矩阵
- 计算过程示意图
3、双三次:由相邻的4 * 4像素计算得出,公式类似于双线性插值;
4、基于像素区域关系:共分三种情况,图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,此情况下可以避免波纹出现;
5、兰索斯插值:由相邻的8 * 8像素计算得出,公式类似于双线性
总结:
- 速度比较:INTER_NEAREST(最近邻插值)>INTER_LINEAR(双线性插值)>INTER_CUBIC(三次样条插值)>INTER_AREA(区域插值)
- OpenCV推荐:如果要缩小图像,通常推荐使用 INTER_AREA插值效果最好;而要放大图像,通常使用 INTER_CUBIC(速度较慢,但效果最好),或者使用 INTER_LINEAR(速度较快,效果还可以)。至于最近邻插值 INTER_NEAREST,一般不推荐使用
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::resize_demo(Mat &image) { Mat zoomin, zoomout; int h = image.rows; int w = image.cols; //resize(输入图像,输出图像,大小变换方法Size(),x方向缩放系数,y方向缩放系数,插值算法) //如果size有值,使用size做放缩插值,否则根据fx与fy卷积 resize(image, zoomin, Size(w / 2, h / 2), 0, 0, INTER_LINEAR); imshow("zoomin", zoomin); resize(image, zoomout, Size(w * 1.5, h * 1.5), 0, 0, INTER_LINEAR); imshow("zoomout", zoomout); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.resize_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果
2.19、图像翻转
quickopencv.h
#pragma once #include<opencv2/opencv.hpp> using namespace cv; class QuickDemo { public: void colorSpace_Demo(Mat &image); void mat_creation_demo(); void pixel_visit_demo(Mat &image); void operators_demo(Mat &image); void tracking_bar_demo(Mat &image); void key_demo(Mat &image); void color_style_demo(Mat &image); void bitwise_demo(Mat &image); void channels_demo(Mat &image); void inrange_demo(Mat &image); void pixel_statistic_demo(Mat &image); void form_paint_random(); void polyline_drawing_demo(); void mouse_drawing_demo(Mat &image); void norm_demo(Mat &image); void resize_demo(Mat &image); void flip_demo(Mat &image); };
quickdemo.cpp
void QuickDemo::flip_demo(Mat &image) { Mat dst; flip(image, dst, 0); //上下翻转 imshow("图像上下翻转", dst); flip(image, dst, 1); //左右翻转 imshow("图像左右翻转", dst); flip(image, dst, -1); //180°旋转 imshow("图像180°翻转", dst); }
test440.cpp
#include<opencv2/opencv.hpp> #include<quickopencv.h> #include<iostream> using namespace cv; using namespace std; int main(int argc, char**argv) { // imread函数的第二个参数有很多,默认为IMREAD_COLOR,还有IMREAD_UNCHANGED,IMREAD_GRAYSCALE,IMREAD_ANYCOLOR等等,实现对不同图片的读取操作 // B,G,R Mat src = imread("D:/images/greenback.jpg"); //Mat为matrix,二维图像都是Mat类型,第一个参数为图片绝对路径 if (src.empty()) { printf("could not load image...\n"); return -1; } //namedWindow("输入窗口", WINDOW_FREERATIO); //不管图片大小,都能进行调整,图像很小可以不使用这个函数 imshow("输入窗口", src); //第一个参数为窗口名 QuickDemo qd; qd.flip_demo(src); waitKey(0); //窗口停留时间,0为一直停留,数值为停留的毫秒数 destroyAllWindows(); //关闭所有打开的窗口 return 0; }
效果