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


    重映射



    实现重映射(remap函数)


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

    
    //---------------------------------【头文件、命名空间包含部分】----------------------------
    //		描述:包含程序所使用的头文件和命名空间
    //------------------------------------------------------------------------------------------------
    #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函数指定的图片存在~! 
    "); 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函数指定的图片存在~! 
    "); 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 << "程序退出...........
    ";
    			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("
    
    			   当前使用的OpenCV版本为:" CV_VERSION);
    	printf("
    
      ----------------------------------------------------------------------------
    ");
    	//输出一些帮助信息  
    	printf("
    	欢迎来到重映射示例程序~
    
    ");
    	printf("
    	按键操作说明: 
    
    "
    		"		键盘按键【ESC】- 退出程序
    "
    		"		键盘按键【1】-  第一种映射方式
    "
    		"		键盘按键【2】- 第二种映射方式
    "
    		"		键盘按键【3】- 第三种映射方式
    "
    		"		键盘按键【4】- 第四种映射方式
    ");
    }
    

    仿射变换

    仿射变换的基本概念


    仿射变换的求法




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




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

    示例程序:仿射变换

    #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函数指定的图片存在~! 
    "); 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("
    
    			   当前使用的OpenCV版本为:" CV_VERSION);
    	printf("
    
      ----------------------------------------------------------------------------
    ");
    
    	//输出一些帮助信息  
    	printf("
    
    		欢迎来到仿射变换综合示例程序
    
    ");
    	printf("		键盘按键【ESC】- 退出程序
    ");
    }
    
    

    直方图均衡化


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




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


    示例程序:直方图均衡化

    
    
  • 相关阅读:
    Beware of GPU memory bandwidth
    XNA中的RenderTarget
    Scene Management Culling
    More on Scene Management
    关于quaternion的笔记
    用XNA显示GPU系统信息
    Scene Management Collision Detection
    些关于引擎设计,Scene Management的文章
    XNA下的中文显示
    Skeletal Model and Skinning Animation
  • 原文地址:https://www.cnblogs.com/xingkongcanghai/p/11205892.html
Copyright © 2020-2023  润新知