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

相关