zoukankan      html  css  js  c++  java
  • 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()函数


    示例程序:直方图均衡化

    
    
  • 相关阅读:
    2020年. NET Core面试题
    java Context namespace element 'component-scan' and its parser class ComponentScanBeanDefinitionParser are only available on JDK 1.5 and higher 解决方法
    vue 淡入淡出组件
    java http的get、post、post json参数的方法
    vue 父子组件通讯案例
    Vue 生产环境解决跨域问题
    npm run ERR! code ELIFECYCLE
    Android Studio 生成apk 出现 :error_prone_annotations.jar (com.google.errorprone:error) 错误
    记忆解析者芜青【总集】
    LwIP应用开发笔记之十:LwIP带操作系统基本移植
  • 原文地址:https://www.cnblogs.com/xingkongcanghai/p/11205892.html
Copyright © 2011-2022 走看看