OpenCV C++案例实战十六《制作哈哈镜图像》

OpenCV C++案例实战十六《制作哈哈镜图像》


前言

本文将使用OpenCV C++ 制作哈哈镜图像。其实原理很简单,就是让图像像素扭曲,将像素重新进行映射。
假设输入图像宽w,高h。图像中心点坐标(cx,cy),图像任意像素点(x,y)到中心点距离 dx=(x-cx),dy=(y-cy),变换半径r。

一、凸透镜

请添加图片描述

制作凸透镜效果(将图像放大)。根据网上查找的变换公式:

	图像放大:凸透镜
	x = (dx / 2)*(sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cx;
	y = (dy / 2)*(sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cy;

 
 

    1.功能源码

    请查看源码注释

    bool Mirror_Magnify(Mat src)
    {
    	/*	
    	图像放大:凸透镜
    	x = (dx / 2)*(sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cx;
    	y = (dy / 2)*(sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cy;
    	*/
    

    Mat canvas = Mat::zeros(src.size(), src.type()); //画布,重新生成哈哈图像

    //图像中心
    int cx = src.cols / 2;
    int cy = src.rows / 2;
    //决定哈哈镜大小
    int radius = 200;

    //图像像素修改
    for (int i = 0; i < src.rows; i++)
    {
    for (int j = 0; j < src.cols; j++)
    {
    //任意像素点到图像中心距离
    int dx = j - cx;
    int dy = i - cy;
    //重新映射像素点位置
    int x = (dx / 2)(sqrt(pow(dx, 2) + pow(dy, 2)) / radius) + cx;
    int y = (dy / 2)(sqrt(pow(dx, 2) + pow(dy, 2)) / radius) + cy;

    for (int c = 0; c < 3; c++)
    {
    //防止越界
    if ((x > 0 && x < src.cols) && (y > 0 && y < src.rows))
    {
    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(y, x)[c];
    }
    }
    }
    }

    imshow(“Mirror_Magnify”, canvas);

    return true;
    }

      2.效果显示

      请添加图片描述

      二、凹透镜

      制作凹透镜效果(将图像缩小)。根据网上查找的变换公式:

      	图像缩小:凹透镜
      	x = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) * compress * cos(atan2(dy, dx)) + cx;
      	y = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) * compress * sin(atan2(dy, dx)) + cy;
      
       
       

        1.功能源码

        请查看源码注释

        bool Mirror_Narrow(Mat src)
        {
        	/*
        	图像缩小:凹透镜
        	x = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) * compress * cos(atan2(dy, dx)) + cx;
        	y = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) * compress * sin(atan2(dy, dx)) + cy;
        	*/
        

        Mat canvas = Mat::zeros(src.size(), src.type());//画布,重新生成哈哈图像

        int compress = 12; //压缩强度
        //图像中心
        int cx = src.cols / 2;
        int cy = src.rows / 2;

        //图像像素修改
        for (int i = 0; i < src.rows; i++)
        {
        for (int j = 0; j < src.cols; j++)
        {
        //任意像素点到图像中心距离
        int dx = j - cx;
        int dy = i - cy;
        //重新映射像素点位置
        int x = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) compress cos(atan2(dy, dx)) + cx;
        int y = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) compress sin(atan2(dy, dx)) + cy;

        for (int c = 0; c < 3; c++)
        {
        //防止越界
        if ((x > 0 && x < src.cols) && (y > 0 && y < src.rows))
        {
        canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(y, x)[c];
        }
        }
        }
        }

        <span class="token function">imshow</span><span class="token punctuation">(</span><span class="token string">"Mirror_Narrow"</span><span class="token punctuation">,</span> canvas<span class="token punctuation">)</span><span class="token punctuation">;</span>
        
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        

        }

          2.效果显示

          请添加图片描述

          三、源码

          #include<iostream>
          #include<opencv2/opencv.hpp>
          using namespace std;
          using namespace cv;
          

          /*
          哈哈镜实现原理:让图像像素扭曲,将像素重新进行映射
          假设输入图像宽w,高h。图像中心点坐标(cx,cy),图像任意像素点(x,y)到中心点距离 dx=(x-cx),dy=(y-cy),变换半径r
          */

          bool Mirror_Magnify(Mat src)
          {
          /*
          图像放大:凸透镜
          x = (dx / 2)(sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cx;
          y = (dy / 2)
          (sqrt(pow(dx, 2) + pow(dy, 2)) / r) + cy;
          */

          Mat canvas = Mat::zeros(src.size(), src.type()); //画布,重新生成哈哈图像

          //图像中心
          int cx = src.cols / 2;
          int cy = src.rows / 2;
          //决定哈哈镜大小
          int radius = 200;

          //图像像素修改
          for (int i = 0; i < src.rows; i++)
          {
          for (int j = 0; j < src.cols; j++)
          {
          //任意像素点到图像中心距离
          int dx = j - cx;
          int dy = i - cy;
          //重新映射像素点位置
          int x = (dx / 2)(sqrt(pow(dx, 2) + pow(dy, 2)) / radius) + cx;
          int y = (dy / 2)(sqrt(pow(dx, 2) + pow(dy, 2)) / radius) + cy;

          for (int c = 0; c < 3; c++)
          {
          //防止越界
          if ((x > 0 && x < src.cols) && (y > 0 && y < src.rows))
          {
          canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(y, x)[c];
          }
          }
          }
          }

          imshow(“Mirror_Magnify”, canvas);

          return true;
          }

          bool Mirror_Narrow(Mat src)
          {
          /*
          图像缩小:凹透镜
          x = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) * compress * cos(atan2(dy, dx)) + cx;
          y = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) * compress * sin(atan2(dy, dx)) + cy;
          */

          Mat canvas = Mat::zeros(src.size(), src.type());//画布,重新生成哈哈图像

          int compress = 12; //压缩强度
          //图像中心
          int cx = src.cols / 2;
          int cy = src.rows / 2;

          //图像像素修改
          for (int i = 0; i < src.rows; i++)
          {
          for (int j = 0; j < src.cols; j++)
          {
          //任意像素点到图像中心距离
          int dx = j - cx;
          int dy = i - cy;
          //重新映射像素点位置
          int x = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) compress cos(atan2(dy, dx)) + cx;
          int y = sqrt(sqrt(pow(dx, 2) + pow(dy, 2))) compress sin(atan2(dy, dx)) + cy;

          for (int c = 0; c < 3; c++)
          {
          //防止越界
          if ((x > 0 && x < src.cols) && (y > 0 && y < src.rows))
          {
          canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(y, x)[c];
          }
          }
          }
          }

          imshow(“Mirror_Narrow”, canvas);

          return true;
          }

          int main()
          {
          Mat src = imread(“test.jpg”);
          if (src.empty())
          {
          cout << “No Image!” << endl;
          system(“pause”);
          return -1;
          }

          Mirror_Magnify(src);
          Mirror_Narrow(src);

          imshow(“test”, src);
          waitKey(0);
          system(“pause”);;
          return 0;
          }


            总结

            本文使用OpenCV C++ 制作哈哈镜图像,关键步骤有以下几点。
            1、了解哈哈镜图像制作原理:根据公式对图像像素进行重新映射。

            • 0
              点赞
            • 0
              收藏
              觉得还不错? 一键收藏
            • 0
              评论
            评论
            添加红包

            请填写红包祝福语或标题

            红包个数最小为10个

            红包金额最低5元

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

            抵扣说明:

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

            余额充值