目录
官方在线帮助文档:OpenCV: OpenCV modules
用OpenCV对图像做一些简单的操作
1. 随机数与随机颜色
2. 多边形绘制与填充
3. 鼠标操作与响应
4. 图像像素类型转换归一化
5. 图像放缩与插值
6. 图像翻转
7. 图像旋转
#include
#include
#include
using namespace cv;
using namespace std;
class demo
{
public:
void random_drawing()
{
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
int width = canvas.cols;
int height = canvas.rows;
RNG rng(12345);
while (true) {
int c = waitKey(100);
if (c == 27) {
break;
}
// 随机坐标
int x1 = rng.uniform(0, width);
int y1 = rng.uniform(0, height);
int x2 = rng.uniform(0, width);
int y2 = rng.uniform(0, height);
// 随机颜色
int b = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int r = rng.uniform(0, 255);
//canvas = Scalar(0, 0, 0);
// 设置每次都只花一条直线,用黑色背景覆盖每次
line(canvas, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 4, LINE_AA, 0);
imshow("随机绘制演示", canvas);
}
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.random_drawing();
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
#include
#include
#include
using namespace cv;
using namespace std;
class demo
{
public:
void polyline_drawing_demo()
{
Mat canvas = 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);
vector pts(5);
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
// 绘制
//polylines(canvas, pts, true, Scalar(0, 0, 255), 2, 8, 0);
// 填充
//fillPoly(canvas, pts, true, Scalar(255, 255, 0), 8, 0);
vector> contours;
contours.push_back(pts);
drawContours(canvas, contours, -1, Scalar(255, 0, 0), 2);
// 2绘制形状,-1填充
imshow("多边形绘制", canvas);
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.polyline_drawing_demo();
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
#include
#include
#include
using namespace cv;
using namespace std;
// 鼠标响应
Point sp(-1, -1);
Point ep(-1, -1);
// 设置一个临时图层,确保显示最后一个图片
Mat temp;
class demo
{
public:
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;
cout << "start point:" << sp << 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);// 解决ROI区域有颜色框的问题
imshow("ROI区域", image(box));
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
imshow("鼠标绘制", image);
// 每次绘制完成之后要更新数据
sp.x = -1;
sp.y = -1;
}
cout << "end point:" << ep << endl;
}
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);
}
cout << "end point:" << ep << endl;
}
}
}
void mouse_drawing_demo(Mat &image)
{
namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
setMouseCallback("鼠标绘制", on_draw,(void*)(&image));
imshow("鼠标绘制", image);
temp = image.clone();
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.mouse_drawing_demo(src);
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
四种归一化方法
最常用的就是NORM_MINMAX归一化方法
关于API函数:
#include
#include
#include
using namespace cv;
using namespace std;
class demo
{
public:
void norm_demo(Mat& image)
{
Mat dst;
cout << image.type() << endl;
image.convertTo(dst, CV_32F);
cout << image.type() << endl;
normalize(image, dst, 1.0, 0, NORM_MINMAX);
cout << dst.type() << endl;
imshow("图像数据归一化", dst);
// CV_8UC3 转换为 CV_32FC3
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.norm_demo(src);
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
图像插值(Image Interpolation)
最常见的四种插值算法
相关应用场景
几何变换,透视变换,插值计算新像素 resize
如果size有值,使用size做放缩插值,否则根据fx与fy卷积
#include
#include
#include
using namespace cv;
using namespace std;
class demo
{
public:
void resize_demo(Mat& image)
{
Mat zoomin, zoomout;
int height = image.rows;
int width = image.cols;
resize(image, zoomin, Size(width * 1.50, height * 1.50), 0, 0, INTER_LINEAR);
imshow("zoomin", zoomin);// 放大
resize(image, zoomout, Size(width / 2.0, height / 2.0), 0, 0, INTER_LINEAR);
imshow("zoomout", zoomout);// 缩小
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.resize_demo(src);
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
#include
#include
#include
using namespace cv;
using namespace std;
class demo
{
public:
void flip_demo(Mat& image)
{
Mat dst;
flip(image, dst, 0);
imshow("图像翻转(上下)", dst);// 上下翻转
flip(image, dst, 1);
imshow("图像翻转(左右)", dst);// 左右反转
flip(image, dst, -1);
imshow("旋转180度", dst);// 旋转180度
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.flip_demo(src);
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
#include
#include
#include
using namespace cv;
using namespace std;
class demo
{
public:
void rotate_demo(Mat& image)
{
Mat dst,M;
int width = image.cols;
int height = image.rows;
M = getRotationMatrix2D(Point2f(width / 2, height / 2), 45, 1.0);
double cos = abs(M.at(0, 0));
double sin = abs(M.at(0, 1));
int new_width = cos * width + sin * height;
int new_height = sin * width + cos * height;
M.at(0, 2) += (new_width / 2 - width / 2);
M.at(1, 2) += (new_height / 2 - height / 2);
warpAffine(image, dst, M, Size(new_width, new_height), INTER_LINEAR, 0, Scalar(255, 255, 0));
imshow("旋转演示", dst);
}
};
int main(int argc, char** argv)
{
Mat src = imread("迪丽热巴.png",IMREAD_UNCHANGED);
// Mat是一种特殊的数据类型格式,是一种二维数组,用来存储图片的数据
// namedWindow("输出窗口", WINDOW_FREERATIO);
// 只有imshow无法调整图片显示窗口的大小,通过namedWindow调整窗口的大小
if (src.empty()) {
cout << "没有找到你的图片" << endl;
return -1;
}
imshow("输出窗口", src);
demo d;
d.rotate_demo(src);
waitKey(0);// 设置图片显示时间
destroyAllWindows();// 释放所有窗口
return 0;
}
写的比较简单,都是直接上代码了,关于每个方法的介绍我准备后期补上,大家先看官方文档的介绍。