zoukankan      html  css  js  c++  java
  • 【练习4.7】使用键盘控制透视变换和仿射变换的变换矩阵:实现拉伸、收缩、扭曲、旋转

    《学习OpenCV》中文版第4章第7题

     注意:操作的使用将输入法状态切换到“英文”状态

    提纲
    题目要求
    程序代码
    结果图片

     

     

     

     

    题目要求:

    a、使用数字键1~9以及数字键与Shift的组合,实现透视变换变换矩阵中对应元素的增大和缩小

    b、使用上下方向键实现仿射变换变换矩阵中对应元素的增大和缩小,以实现对图片的缩放。

    c、使用左右方向键实现仿射变换变换矩阵中对应元素的增大和缩小,以实现对图片的旋转。

    程序代码:

      1 #include "stdafx.h"
      2 #include <cv.h>
      3 #include <highgui.h>
      4 #include <iostream>
      5 using namespace cv;
      6 using namespace std;
      7 //函数声明-->--->-->--->-->--->-->--->//
      8 
      9 int shiftKeyHandler(int key);
     10 
     11 //<--<--<--<--<--<--<--<--<--函数声明//
     12 
     13 int _tmain(int argc, _TCHAR* argv[])
     14 {
     15     const char * fileName = "D:\Work\Work_Programming\Source\Image\lena.jpg";
     16     IplImage * img = cvLoadImage(fileName, CV_LOAD_IMAGE_UNCHANGED);    
     17     assert(img);
     18     
     19     IplImage * dst = cvCloneImage(img);
     20     dst->origin = img->origin;
     21     cvZero(dst);
     22 
     23     IplImage * affinedImage = NULL;
     24     CvPoint2D32f center = cvPoint2D32f(img->width / 2, img->height/2);
     25     double angle = -20.0;
     26     double scale = 1.0;    
     27 
     28     cvNamedWindow("ExerciseWindow", CV_WINDOW_AUTOSIZE);    
     29     cvNamedWindow("透视变换", CV_WINDOW_AUTOSIZE);
     30     cvNamedWindow("图片缩放旋转", CV_WINDOW_AUTOSIZE);
     31 
     32     cvShowImage("ExerciseWindow", img);
     33 
     34     CvMat * warp_matrix = cvCreateMatHeader(3, 3, CV_32FC1);     
     35     float matDataSource[9] = { 0.372190326f, 0.216031685f, 25.6000004f,
     36         -0.213343531f, 0.600807548f, 168.960007f,
     37         -0.00104052317f, 0.000641974097f, 1.00000000f };
     38     warp_matrix->data.fl = matDataSource;
     39     
     40     CvMat *rot_mat = cvCreateMat(2, 3, CV_32FC1);
     41 
     42     while (true)
     43     { 
     44         int key = cvWaitKey(0);
     45         
     46         //---------------------------透视变换:开始--------------------------------//
     47         //使用1~9键盘数字或与Shift的结合控制透视变换矩阵的9个元素
     48 
     49         //当没有按下Shift键的时候
     50         if (key >= 49 && key <= 57)    //按键1~9的ASCII码是49~57
     51         {
     52             matDataSource[key % 49] += matDataSource[key % 49] / 10.0f;    //这种方式可以省掉使用switch的大段代码
     53         }
     54         else//当按下Shift键的时候
     55         {
     56             if (key == 27)
     57             {
     58                 break;
     59             }
     60 
     61             int subscript = shiftKeyHandler(key);
     62             if (subscript != -1)
     63             {
     64                 //题目要求是对应数据最小值是0,但实际操作中发现,有负值的情况比较理想
     65                 /*float temp = matDataSource[subscript] / 10.0f;
     66                 if ((matDataSource[subscript] -= matDataSource[subscript] / 10.0f) < 0.000001f)
     67                 {
     68                     matDataSource[subscript] += temp;
     69                 }*/
     70 
     71                 matDataSource[subscript] -= matDataSource[subscript] / 10.0f;
     72             }
     73             else
     74             {
     75                 cout << "请在程序获取输入焦点的情况下将输入法切换到英文状态再试!" << endl;
     76             }
     77         }
     78 
     79         cvWarpPerspective(img, dst, warp_matrix);
     80         cvShowImage("透视变换", dst);
     81 
     82         //---------------------------透视变换:结束--------------------------------//        
     83 
     84         //---------------------------图片缩放与旋转:开始(仿射变换方法)----------------//
     85         //使用上下箭头即“↑”“↓”控制图片放大缩小
     86         //使用上下箭头即“←”“→”控制图片旋转
     87 
     88         if (key == 2490368 || key == 2621440 || key == 2424832 || key == 2555904)
     89         {
     90             affinedImage = cvCloneImage(img);
     91             affinedImage->origin = img->origin;
     92             cvZero(affinedImage);
     93             
     94             if (key == 2490368)//方向键“↑”
     95             {
     96                 scale += scale*0.2;
     97             }
     98 
     99             if (key == 2621440)
    100             {
    101                 scale -= scale*0.2;
    102             }
    103 
    104             if (key == 2424832)//方向键“←”
    105             {
    106                 angle -= 10.0;
    107             }
    108 
    109             if (key == 2555904)
    110             {
    111                 angle += 10.0;
    112             }
    113 
    114             cv2DRotationMatrix(center, angle, scale, rot_mat);
    115             cvWarpAffine(img, affinedImage, rot_mat);
    116             cvShowImage("图片缩放旋转", affinedImage);
    117         }
    118         else if (key == 27)
    119         {
    120             break;
    121         }
    122 
    123         //---------------------------图片缩放与旋转:结束--------------------------------//    
    124     }
    125 
    126     //cvWaitKey(0);
    127 
    128     cvReleaseImage(&img);
    129     cvReleaseImage(&dst);
    130     cvReleaseImage(&affinedImage);
    131     cvDestroyWindow("ExerciseWindow");     
    132     cvDestroyWindow("透视变换");
    133     cvDestroyWindow("图片缩放旋转");
    134 
    135     return 0;
    136 }
    137 
    138 //当同时按下Shift键时,处理key的值,使其结果方便使用
    139 int shiftKeyHandler(int key)
    140 {
    141     //输入法分为英文和中文两种输入状态,本程序只开了英文状态,当然,实际开发中也可在使用代码控制输入法状态
    142     switch (key)
    143     {
    144     case '!':return 0;
    145     case '@':return 1;
    146     case '#':return 2;
    147     case '$':return 3;
    148     case '%':return 4;
    149     case '^':return 5;
    150     case '&':return 6;
    151     case '*':return 7;
    152     case '(':return 8;
    153     default:
    154         return -1;        
    155     }    
    156 }

    结果图片

     

     

  • 相关阅读:
    键盘钩子在C#中的设计
    C++基础(学习笔记)
    WinCE5.0移动平台开发笔记(OpenNETCF.Desktop.Communication连接和断开使用心得)
    the underlying connection was closed:the server committed a protocol violation
    WinCE5.0移动平台开发笔记(c#中使用多线程访问winform中控件的若干问题(zt))
    WinCE5.0移动平台开发笔记(.Net主线程扑捉子线程中的异常)
    配置ActiveX控件在网页中下载安装
    C#值类型和装箱
    磁卡、条码卡、IC卡、CPU卡、RFID等常识(zt)
    CAB压缩工具安装(右键生成CAB压缩包)
  • 原文地址:https://www.cnblogs.com/tingshuixuan2012/p/OpenCVExercises4_7.html
Copyright © 2011-2022 走看看