opencv 5 图像转换(3 重映射 仿射变换 直方图均衡化)

重映射

1589120-20190718075843064-37864150.png
1589120-20190718075915542-1053659027.png
1589120-20190718075944106-356872268.png

实现重映射(remap函数)

1589120-20190718080126062-1884125453.png
1589120-20190718081014368-774267682.png

基础示例程序:基本重映射

//---------------------------------【头文件、命名空间包含部分】----------------------------
//      描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;


//-----------------------------------【main( )函数】--------------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
    //【0】变量定义
    Mat srcImage, dstImage;
    Mat map_x, map_y;

    //【1】载入原始图
    srcImage = imread("1.jpg", 1);
    if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    imshow("原始图", srcImage);

    //【2】创建和原始图一样的效果图,x重映射图,y重映射图
    dstImage.create(srcImage.size(), srcImage.type());
    map_x.create(srcImage.size(), CV_32FC1);
    map_y.create(srcImage.size(), CV_32FC1);

    //【3】双层循环,遍历每一个像素点,改变map_x & map_y的值
    for (int j = 0; j < srcImage.rows; j++)
    {
        for (int i = 0; i < srcImage.cols; i++)
        {
            //改变map_x & map_y的值. 
            map_x.at<float>(j, i) = static_cast<float>(i);
            map_y.at<float>(j, i) = static_cast<float>(srcImage.rows - j);
        }
    }

    //【4】进行重映射操作
    //此句代码的OpenCV2版为:
    //remap( srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );
    //此句代码的OpenCV3版为:
    remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));

    //【5】显示效果图
    imshow("【程序窗口】", dstImage);
    waitKey();

    return 0;
}

综合示例程序:实现多种重映射
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;


//-----------------------------------【宏定义部分】-------------------------------------------- 
//  描述:定义一些辅助宏 
//------------------------------------------------------------------------------------------------ 
#define WINDOW_NAME "【程序窗口】"        //为窗口标题定义的宏 


//-----------------------------------【全局变量声明部分】--------------------------------------
//          描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage, g_dstImage;
Mat g_map_x, g_map_y;


//-----------------------------------【全局函数声明部分】--------------------------------------
//          描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
int update_map(int key);
static void ShowHelpText();//输出帮助文字

//-----------------------------------【main( )函数】--------------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
    //改变console字体颜色
    system("color 5F");

    //显示帮助文字
    ShowHelpText();

    //【1】载入原始图
    g_srcImage = imread("1.jpg", 1);
    if (!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    imshow("原始图", g_srcImage);

    //【2】创建和原始图一样的效果图,x重映射图,y重映射图
    g_dstImage.create(g_srcImage.size(), g_srcImage.type());
    g_map_x.create(g_srcImage.size(), CV_32FC1);
    g_map_y.create(g_srcImage.size(), CV_32FC1);

    //【3】创建窗口并显示
    namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
    imshow(WINDOW_NAME, g_srcImage);

    //【4】轮询按键,更新map_x和map_y的值,进行重映射操作并显示效果图
    while (1)
    {
        //获取键盘按键  
        int key = waitKey(0);

        //判断ESC是否按下,若按下便退出  
        if ((key & 255) == 27)
        {
            cout << "程序退出...........\n";
            break;
        }

        //根据按下的键盘按键来更新 map_x & map_y的值. 然后调用remap( )进行重映射
        update_map(key);
        //此句代码的OpenCV2版为:
        //remap( g_srcImage, g_dstImage, g_map_x, g_map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );
        //此句代码的OpenCV3版为:
        remap(g_srcImage, g_dstImage, g_map_x, g_map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));

        //显示效果图
        imshow(WINDOW_NAME, g_dstImage);
    }
    return 0;
}

//-----------------------------------【update_map( )函数】--------------------------------
//          描述:根据按键来更新map_x与map_x的值
//----------------------------------------------------------------------------------------------
int update_map(int key)
{
    //双层循环,遍历每一个像素点
    for (int j = 0; j < g_srcImage.rows; j++)
    {
        for (int i = 0; i < g_srcImage.cols; i++)
        {
            switch (key)
            {
            case '1': // 键盘【1】键按下,进行第一种重映射操作
                if (i > g_srcImage.cols*0.25 && i < g_srcImage.cols*0.75 && j > g_srcImage.rows*0.25 && j < g_srcImage.rows*0.75)
                {
                    g_map_x.at<float>(j, i) = static_cast<float>(2 * (i - g_srcImage.cols*0.25) + 0.5);
                    g_map_y.at<float>(j, i) = static_cast<float>(2 * (j - g_srcImage.rows*0.25) + 0.5);
                }
                else
                {
                    g_map_x.at<float>(j, i) = 0;
                    g_map_y.at<float>(j, i) = 0;
                }
                break;
            case '2':// 键盘【2】键按下,进行第二种重映射操作
                g_map_x.at<float>(j, i) = static_cast<float>(i);
                g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j);
                break;
            case '3':// 键盘【3】键按下,进行第三种重映射操作
                g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols - i);
                g_map_y.at<float>(j, i) = static_cast<float>(j);
                break;
            case '4':// 键盘【4】键按下,进行第四种重映射操作
                g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols - i);
                g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j);
                break;
            }
        }
    }
    return 1;
}

//-----------------------------------【ShowHelpText( )函数】----------------------------------  
//      描述:输出一些帮助信息  
//----------------------------------------------------------------------------------------------  
static void ShowHelpText()
{
    //输出欢迎信息和OpenCV版本
    printf("\n\n\t\t\t   当前使用的OpenCV版本为:" CV_VERSION);
    printf("\n\n  ----------------------------------------------------------------------------\n");
    //输出一些帮助信息  
    printf("\n\t欢迎来到重映射示例程序~\n\n");
    printf("\n\t按键操作说明: \n\n"
        "\t\t键盘按键【ESC】- 退出程序\n"
        "\t\t键盘按键【1】-  第一种映射方式\n"
        "\t\t键盘按键【2】- 第二种映射方式\n"
        "\t\t键盘按键【3】- 第三种映射方式\n"
        "\t\t键盘按键【4】- 第四种映射方式\n");
}

仿射变换

仿射变换的基本概念

1589120-20190718083132608-323054328.png
1589120-20190718083739577-245427765.png

仿射变换的求法

1589120-20190718083832831-576146426.png
1589120-20190718083907455-1834798459.png
1589120-20190718084149273-953538315.png
1589120-20190718084304047-676789531.png

进行仿射变换:warpAffine()函数

1589120-20190718084635655-1044322177.png
1589120-20190718084652753-1688509539.png
1589120-20190718084703687-550579229.png
1589120-20190718084716027-1006743597.png

计算二维旋转变换矩阵:getRotationMatrix2D()函数

1589120-20190718084826901-2063009846.png

示例程序:仿射变换
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;


//-----------------------------------【宏定义部分】-------------------------------------------- 
//      描述:定义一些辅助宏 
//------------------------------------------------------------------------------------------------ 
#define WINDOW_NAME1 "【原始图窗口】"                  //为窗口标题定义的宏 
#define WINDOW_NAME2 "【经过Warp后的图像】"        //为窗口标题定义的宏 
#define WINDOW_NAME3 "【经过Warp和Rotate后的图像】"        //为窗口标题定义的宏 



//-----------------------------------【全局函数声明部分】--------------------------------------
//      描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
static void ShowHelpText();


//-----------------------------------【main( )函数】--------------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main()
{
    //【0】改变console字体颜色
    system("color 1F");

    //【0】显示欢迎和帮助文字
    ShowHelpText();

    //【1】参数准备
    //定义两组点,代表两个三角形
    Point2f srcTriangle[3];
    Point2f dstTriangle[3];
    //定义一些Mat变量
    Mat rotMat(2, 3, CV_32FC1);
    Mat warpMat(2, 3, CV_32FC1);
    Mat srcImage, dstImage_warp, dstImage_warp_rotate;

    //【2】加载源图像并作一些初始化
    srcImage = imread("1.jpg", 1);
    if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    // 设置目标图像的大小和类型与源图像一致
    dstImage_warp = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());

    //【3】设置源图像和目标图像上的三组点以计算仿射变换
    srcTriangle[0] = Point2f(0, 0);
    srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0);
    srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1));

    dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols*0.0), static_cast<float>(srcImage.rows*0.33));
    dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols*0.65), static_cast<float>(srcImage.rows*0.35));
    dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols*0.15), static_cast<float>(srcImage.rows*0.6));

    //【4】求得仿射变换
    warpMat = getAffineTransform(srcTriangle, dstTriangle);

    //【5】对源图像应用刚刚求得的仿射变换
    warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());

    //【6】对图像进行缩放后再旋转
    // 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵
    Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);
    double angle = -50.0;
    double scale = 0.6;
    // 通过上面的旋转细节信息求得旋转矩阵
    rotMat = getRotationMatrix2D(center, angle, scale);
    // 旋转已缩放后的图像
    warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());


    //【7】显示结果
    imshow(WINDOW_NAME1, srcImage);
    imshow(WINDOW_NAME2, dstImage_warp);
    imshow(WINDOW_NAME3, dstImage_warp_rotate);

    // 等待用户按任意按键退出程序
    waitKey(0);

    return 0;
}


//-----------------------------------【ShowHelpText( )函数】----------------------------------  
//      描述:输出一些帮助信息  
//----------------------------------------------------------------------------------------------  
static void ShowHelpText()
{

    //输出欢迎信息和OpenCV版本
    
    printf("\n\n\t\t\t   当前使用的OpenCV版本为:" CV_VERSION);
    printf("\n\n  ----------------------------------------------------------------------------\n");

    //输出一些帮助信息  
    printf("\n\n\t\t欢迎来到仿射变换综合示例程序\n\n");
    printf("\t\t键盘按键【ESC】- 退出程序\n");
}

直方图均衡化

1589120-20190718132650429-1330592555.png
1589120-20190718132724063-356164481.png

直方图均衡化的概念和特点

1589120-20190718132851204-968051852.png
1589120-20190718132907955-1958151662.png
1589120-20190718132934620-1808251100.png
1589120-20190718132952613-318051064.png

实现直方图均衡化:equalizeHist()函数

1589120-20190718133223434-111379927.png
1589120-20190718133235480-1732222468.png

示例程序:直方图均衡化

1589120-20190718133319078-1695632360.png

转载于:https://www.cnblogs.com/xingkongcanghai/p/11205892.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值