歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenCV 實現哈哈鏡效果

OpenCV 實現哈哈鏡效果代碼,有參考別人的代碼

先看實現的效果:

實現效果:

 

// haha_mirror.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"

#include<iostream>


#include "cv.h"
#include "highgui.h"
#include "math.h"
#include "opencv2/core/core.hpp"

#pragma comment(lib,"opencv_core2410d.lib")             
#pragma comment(lib,"opencv_highgui2410d.lib")             
#pragma comment(lib,"opencv_imgproc2410d.lib") 

 

#define DOWNRESIZE 0 // 縮小
#define UPRESIZE  1 // 放大
#define HORAO      2 // 水平外凹
#define HORTU      3 // 水平外凸
#define LADDER    4 // 梯形變形
#define TRIANGLE  5 // 三角形變形
#define SSHAPE    6 // S形變形
#define WAVESHAPE  7 // 波浪形變形
#define Concentrated 8 //集中形變形
#define Scattered  9 // 散開形變形

#define RANGE    100 // 水平外凹或外凸的幅度
#define PI        3.1415926

using namespace std;
using namespace cv;

void MaxFrame(IplImage* frame)
{
 uchar* old_data = (uchar*)frame->imageData;
 uchar* new_data = new uchar[frame->widthStep * frame->height];

 int center_X = frame->width / 2;
 int center_Y = frame->height / 2;
 int radius = 400;
 int newX = 0;
 int newY = 0;

 int real_radius = (int)(radius / 2.0);
 for (int i = 0; i < frame->width; i++)
 {
  for (int j = 0; j < frame->height; j++)
  {
   int tX = i - center_X;
   int tY = j - center_Y;

   int distance = (int)(tX * tX + tY * tY);
   if (distance < radius * radius)
   {
    newX = (int)((float)(tX) / 2.0);
    newY = (int)((float)(tY) / 2.0);

    newX = (int) (newX * (sqrt((double)distance) / real_radius));
    newX = (int) (newX * (sqrt((double)distance) / real_radius));

    newX = newX + center_X;
    newY = newY + center_Y;

    new_data[frame->widthStep * j + i * 3] = old_data[frame->widthStep * newY + newX * 3];
    new_data[frame->widthStep * j + i * 3 + 1] =old_data[frame->widthStep * newY + newX * 3 + 1];
    new_data[frame->widthStep * j + i * 3 + 2] =old_data[frame->widthStep * newY + newX * 3 + 2];
   }
   else
   {
    new_data[frame->widthStep * j + i * 3] =  old_data[frame->widthStep * j + i * 3];
    new_data[frame->widthStep * j + i * 3 + 1] =  old_data[frame->widthStep * j + i * 3 + 1];
    new_data[frame->widthStep * j + i * 3 + 2] =  old_data[frame->widthStep * j + i * 3 + 2];
   }
  }
 }
 memcpy(old_data, new_data, sizeof(uchar) * frame->widthStep * frame->height);
 delete[] new_data;
}


void MinFrame(IplImage* frame)
{
 uchar* old_data = (uchar*)frame->imageData;
 uchar* new_data = new uchar[frame->widthStep * frame->height];

 int center_X = frame->width / 2;
 int center_Y = frame->height / 2;

 int radius = 0;
 double theta = 0;
 int newX = 0;
 int newY = 0;

 for (int i = 0; i < frame->width; i++)
 {
  for (int j = 0; j < frame->height; j++)
  {
   int tX = i - center_X;
   int tY = j - center_Y;

   theta = atan2((double)tY, (double)tX);
   radius = (int)sqrt((double)(tX * tX) + (double) (tY * tY));
   int newR = (int)(sqrt((double)radius) * 12);
   newX = center_X + (int)(newR * cos(theta));
   newY = center_Y + (int)(newR * sin(theta));

   if (!(newX > 0 && newX < frame->width))
   {
    newX = 0;
   }
   if (!(newY > 0 && newY < frame->height))
   {
    newY = 0;
   }

   new_data[frame->widthStep * j + i * 3] = old_data[frame->widthStep * newY + newX * 3];
   new_data[frame->widthStep * j + i * 3 + 1] =old_data[frame->widthStep * newY + newX * 3 + 1];
   new_data[frame->widthStep * j + i * 3 + 2] =old_data[frame->widthStep * newY + newX * 3 + 2];
  }
 }
 memcpy(old_data, new_data, sizeof(uchar) * frame->widthStep * frame->height);
 delete[] new_data;
}

// 哈哈鏡制作
int main( int argc, char** argv )
{
 IplImage* pImg; //聲明IplImage指針
 IplImage* pImg1; //聲明IplImage指針
 int i,j;
 int method = 0;
 CvSize size;
 double tmp;

 method = 8;
 //method = HORAO;

 //載入圖像
 pImg = cvLoadImage( "lena.jpg", 1);
 cvNamedWindow( "Image", 1 );//創建窗口
 cvShowImage( "Image", pImg );//顯示圖像
 printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg->imageSize, pImg->height, pImg->width, pImg->nChannels);

 //MaxFrame(pImg);
 //MinFrame(pImg);

 switch(method)
 {
  // 圖像縮小
 case DOWNRESIZE:
  size = cvGetSize(pImg);
  size.width = (size.width>>3)<<2; // 在OpenCV裡邊,widthStep必須是4的倍數,從而實現字節對齊,有利於提高運算速度。
  size.height =  size.height>>1;
  pImg1 = cvCreateImage( size, IPL_DEPTH_8U, 1);
  printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
  for(i=0;i<pImg1->height;i++)
   for(j=0;j<pImg1->width;j++)
   {
    pImg1->imageData[i*pImg1->width+j] = pImg->imageData[i*2*pImg->width+j*2];
   }
   break;
   // 圖像放大
 case UPRESIZE:
  /* 添加代碼 */
  break;
  // 水平外凹
 case HORAO:
  pImg1 = cvCreateImage( cvGetSize(pImg), IPL_DEPTH_8U, 1);
  printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
  for(i=0;i<pImg1->height;i++)
  {
   tmp = RANGE*sin(i*PI/pImg1->height);
   for(j=tmp;j<pImg1->width-tmp;j++)
   {
    pImg1->imageData[i*pImg1->width+j] = pImg->imageData[i*pImg->width+(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp))];
   }
  }
  break;
  // 水平外凸
 case HORTU:
  /* 添加代碼 */
  break;
  // 梯形變形
 case LADDER:
  /* 添加代碼 */
  break;
  // 三角形變形
 case TRIANGLE:
  /* 添加代碼 */
  break;
  // S形變形
 case SSHAPE:
  /* 添加代碼 */
  break;
  // 波浪形變形
 case WAVESHAPE:
  /* 添加代碼 */
  break;
 case Concentrated:
  MaxFrame(pImg);
  break;
 case Scattered:
  MinFrame(pImg);
  break;
 default:
  printf("no method support\n");
  break;
 }

 // 顯示結果
 cvNamedWindow( "Image1", 1 );//創建窗口
 cvShowImage( "Image1", pImg );//顯示圖像

 cvWaitKey(0); //等待按鍵

 //銷毀窗口 釋放內存
 cvDestroyWindow( "Image" );//銷毀窗口
 cvReleaseImage( &pImg ); //釋放圖像
 cvDestroyWindow( "Image1" );//銷毀窗口
 cvReleaseImage( &pImg1 ); //釋放圖像

 return 0;

}

未完待續。。應該還有其他的算法,我再找找。

--------------------------------------分割線 --------------------------------------

Ubuntu Linux下安裝OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm

Ubuntu 12.04 安裝 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm

CentOS下OpenCV無法讀取視頻文件 http://www.linuxidc.com/Linux/2011-07/39295.htm

Ubuntu 12.04下安裝OpenCV 2.4.5總結 http://www.linuxidc.com/Linux/2013-06/86704.htm

Ubuntu 10.04中安裝OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm

基於QT和OpenCV的人臉識別系統 http://www.linuxidc.com/Linux/2011-11/47806.htm

[翻譯]Ubuntu 14.04, 13.10 下安裝 OpenCV 2.4.9  http://www.linuxidc.com/Linux/2014-12/110045.htm

--------------------------------------分割線 --------------------------------------

OpenCV的詳細介紹:請點這裡
OpenCV的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved