OpenCV学习笔记(4)
大纲
1.数据操作与响应
2.图像的放缩 和 插值
3.图像的反转
4.图像的旋转
5.缩放+旋转+镜像
1.数据操作与响应
函数:
setMouseCallback("鼠标绘制", on_draw, (void*)(&image));
效果图:
source code
(1)设置鼠标 点的初始值(按下和弹起)、矩阵的备份
Point sp(-1,-1); //起始点的初始值(鼠标按下)
Point ep(-1,-1); //结束点的初始值(鼠标弹起)
Mat temp;
(2)鼠标绘制回调函数
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; //鼠标弹起时候的坐标绘制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); //定义矩形
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0); //在图片上绘制矩形
temp.copyTo(image); //弹起鼠标擦除擦除之前所有图像
imshow("ROI区域", image(box)); //region of interest 感兴趣的区域
imshow("鼠标绘制", image);
}
//ready for next drawing(reset)
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);
}
}
}
}
(3)鼠标绘制函数
void QuickDemo::mouse_drawing_demo(Mat& image)
{
namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
setMouseCallback("鼠标绘制", on_draw, (void*)(&image));
imshow("鼠标绘制", image);
temp = image.clone(); //把图片copy到temp中。
}
2.图像的放缩 和 插值
函数:resize(图片,输出图片,缩放尺寸,水平缩放,垂直缩放,插值方法)
插值方法(image interpolation)
如果size有值,使用size做放缩插值,否则根据fx与fy卷积。
效果图(缩小两倍,方法1.5倍)
source code...
void QuickDemo::revise_demo(Mat& image)
{
Mat zoomin, zoomout;
int h = image.rows;
int w = image.cols;
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);
}
3.图像的反转
函数
flip(image, dst, 1); //parameter 0:上下反转,1左右反转,-1对角线反转 180度旋转
效果图
source code...
void QuickDemo::image_mirror(Mat& image)
{
Mat dst;
flip(image, dst, 0); //parameter 0:上下反转,1左右反转,-1对角线反转 180度旋转
imshow("图像翻转", dst);
}
4.图像的旋转
函数
(1)旋转矩阵函数
M =getRotationMatrix2D(旋转中心,旋转角度,缩放比例); //获取旋转矩阵
(2)旋转映射
warpAffine(原图, 目标兔, M, Size(nw, nh), INTER_LINEAR, 0, Scalar(255, 255, 255)); //图像旋转
效果图
(3)source code
void QuickDemo::rotation_demo(Mat& image)
{
Mat dst, M;
int w = image.cols;
int h = image.rows;
M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0); //获取旋转矩阵
/*1.旋转中心 2.旋转角度 3.缩放的比例
===>>>修改为这个 时候的 重新修改图片的尺寸*/
double cos = abs(M.at(0,0)); //绝对值absolution
double sin = abs(M.at(0,1)); //绝对值absolution
int nw = cos * w + sin * h;
int nh = sin * w + cos * h;
//
//中心点的偏移量
M.at(0, 2) = M.at(0, 2) + (nw / 2 - w / 2);
M.at(1, 2) = M.at(1, 2) + (nh / 2 - h / 2);
; std::cout << M << std::endl;
//输出重新的内容,图片新的尺寸,新的旋转中心
warpAffine(image, dst, M, Size(nw, nh), INTER_LINEAR, 0, Scalar(255, 255, 255)); //图像旋转
//warpAffine(image, dst, M, image.size(), INTER_LINEAR, 0, Scalar(255, 255, 255)); //图像旋转
imshow("旋转演示", dst);
}
(4)源码解释
1.定义旋转矩阵、目标矩阵、通过函数获得旋转矩阵
Mat dst, M;
int w = image.cols;
int h = image.rows;
M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0); //获取旋转矩阵
2.获得旋转后的 新的旋转矩阵的图片的 尺寸
double cos = abs(M.at(0,0)); //绝对值absolution
double sin = abs(M.at(0,1)); //绝对值absolution
int nw = cos * w + sin * h;
int nh = sin * w + cos * h;
3.对新图片的旋转矩阵中心点进行偏移
M.at(0, 2) = M.at(0, 2) + (nw / 2 - w / 2);
M.at(1, 2) = M.at(1, 2) + (nh / 2 - h / 2);
4.输出旋转后的图片,以新的图片的尺寸为基础
warpAffine(image, dst, M, Size(nw, nh), INTER_LINEAR, 0, Scalar(255, 255, 255)); //图像旋转
//warpAffine(image, dst, M, image.size(), INTER_LINEAR, 0, Scalar(255, 255, 255)); //图像旋转
imshow("旋转演示", dst);
5.结束
5.缩放+旋转+镜像
效果图
source code
//缩放,旋转,镜像
void QuickDemo::revise_mirror_rotation(Mat& image)
{
//1.缩放(revise)
Mat dst_zoom,dst_rotation,dst_mirror;
int w = image.cols;
int h = image.rows;
resize(image, dst_zoom, Size(w / 2, h / 2), 0, 0, INTER_LINEAR); //修改后的尺寸resize :balabala
//缩放后图像的尺寸
int w1 = dst_zoom.cols;
int h1 = dst_zoom.rows;
//2.旋转(rotation):旋转后别忘记更新中心坐标,或对坐标进行偏移。
//确定旋转矩阵,旋转中心,旋转角度55,缩放比例1.0
Mat M = getRotationMatrix2D(Point2f(w1 / 2, h1 / 2), 55, 1.0);
//通过几何变化得到新的图片的尺寸
//1.acquire cos and sin
double cos = abs(M.at(0, 0));
double sin = abs(M.at(0, 1));
//2.得到图片新的尺寸
int w2 = cos * w1 + sin * h1;
int h2 = sin * w1 + cos * h1;
//3.对旋转矩阵进行 中心点偏移
M.at(0, 2) = M.at(0, 2) + (w2 / 2 - w1 / 2);
M.at(1, 2) = M.at(1, 2) + (h2 / 2 - h1 / 2);
//4.输出更新旋转矩阵后的旋转矩阵(旋转矩阵)
warpAffine(dst_zoom, dst_rotation,M, Size(w2, h2), INTER_LINEAR, 0, Scalar(255, 255, 255));
//3.镜像(mirror)
flip(dst_rotation, dst_mirror, -1);
//4.显示(display)
imshow("dst_zoom", dst_zoom);
imshow("dst_rotation", dst_rotation);
imshow("dst_mirror", dst_mirror);
}
data:2021-12-23