#include "stdafx.h"
#include<stdio.h>
#include<opencv2\highgui\highgui.hpp>
#include"cv.h"
#include"math.h"
#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 ROTATION 8 //旋转图像
#define RANGE 100 // 水平外凹或外凸的幅度
#define PI 3.1415926
// 哈哈镜制作
//旋转图像的函数
IplImage* FitRotate(IplImage* Img_old, double angle)
{
IplImage* Img_tmp = NULL;
double anglerad = (CV_PI* (angle / 180));
int newheight = int(fabs((sin(anglerad)*Img_old->width)) + fabs((cos(anglerad)*Img_old->height)));
int newwidth = int(fabs((sin(anglerad)*Img_old->height)) + fabs((cos(anglerad)*Img_old->width)));
Img_tmp = cvCreateImage(cvSize(newwidth, newheight), IPL_DEPTH_8U, 1);
cvFillImage(Img_tmp, 0);//目的图像 使用扩展的大小
IplImage* dst = cvCloneImage(Img_old);//目的图像 与原图像等大
float m[6];
CvMat M = cvMat(2, 3, CV_32F, m);
int w = Img_old->width;
int h = Img_old->height;
m[0] = (float)(cos(angle*CV_PI / 180.));
m[1] = (float)(sin(angle*CV_PI / 180.));
m[2] = w*0.5f;
m[3] = -m[1];
m[4] = m[0];
m[5] = h*0.5f;
cvGetQuadrangleSubPix(Img_old, dst, &M);
cvGetQuadrangleSubPix(Img_old, Img_tmp, &M);
return Img_tmp;
}
int main(int argc, char** argv)
{
IplImage* pImg; //声明IplImage指针
IplImage* pImg1=NULL; //声明IplImage指针
int i, j;
int method = 1;
double angle = 45.0;
CvSize size;
double tmp;
method = DOWNRESIZE;
//method = UPRESIZE;
//method = HORAO;
//method = HORTU;
//method = LADDER;
//method = TRIANGLE;
//method = SSHAPE;
//method = WAVESHAPE;
//method = ROTATION;
//载入图像
pImg = cvLoadImage("pic.jpg", 0);
cvNamedWindow("Image", 1);//创建窗口
cvShowImage("Image", pImg);//显示图像
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg->imageSize, pImg->height, pImg->width, pImg->nChannels);
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:
size = cvGetSize(pImg);
size.width = (size.width >> 2) << 3; // 在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);
//cvResize(pImg, pImg1, CV_INTER_AREA);
for (i = 0; i<pImg1->height; i++)
for (j = 0; j<pImg1->width; j++)
{
pImg1->imageData[i*pImg1->width + j] = pImg->imageData[(int)(i / 2 + 0.5)*pImg->width + (int)(j / 2 + 0.5)];
}
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:
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 =abs(RANGE*sin((i+pImg1->height/2)*PI/pImg1->height));
tmp = abs(RANGE*(sin(i*PI / pImg1->height) - 1));
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 LADDER:
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(2*i*PI/pImg1->height)+1);
//tmp=pImg1->width*(1-i/pImg1->height)/4;
tmp = (pImg->width - pImg->width*i / pImg->height) / 4;
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 TRIANGLE:
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=(pImg1->width*(-i/pImg1->height+1))/4;
tmp = (pImg->width - pImg->width*i / pImg->height) / 2;
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;
// S形变形
case SSHAPE:
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(2 * i*PI / pImg1->height) + 1);
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 WAVESHAPE:
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 = 30 * (sin(5 * i*PI / pImg1->height) + 1);
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 ROTATION:
pImg1 = FitRotate(pImg, angle);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
break;
default:
printf("no method support\n");
break;
}
// 显示结果
cvNamedWindow("Image1", 1);//创建窗口
cvShowImage("Image1", pImg1);//显示图像
//cvSaveImage("水平内凹.jpg", pImg1);
cvWaitKey(0); //等待按键
//销毁窗口 释放内存
cvDestroyWindow("Image");//销毁窗口
cvReleaseImage(&pImg); //释放图像
cvDestroyWindow("Image1");//销毁窗口
cvReleaseImage(&pImg1); //释放图像
return 0;
}