#include <opencv2/opencv.hpp> using namespace cv; using namespace std; #define RATIO 0.25 #define WEIGHT 2 #define DELTA 20 #define ALPHA 0.15 #define BETA 0.85 int _tmain(int argc, _TCHAR* argv[]) { // 准备源图像 IplImage* src = cvLoadImage("..\\image.jpg"); int width = src->width; int height = src->height; //cvSetImageROI(src, cvRect(0, (1-RATIO)*height, width, height)); int mir_w = width; int mir_h = RATIO*height; IplImage* mir = cvCreateImage(cvSize(width, RATIO*height) ,src->depth, src->nChannels); //cvCopy(src, mir);// 拷贝有bug //cvResetImageROI(src); // 从源图像拷贝1/4图像作为镜像图像 for (int i=0; i<width; i++) { for (int j=(1-RATIO)*height; j<height; j++) { uchar* pSrc = &CV_IMAGE_ELEM(src, uchar, j, i*3); uchar* pDst = &CV_IMAGE_ELEM(mir, uchar, (int)(j-(1-RATIO)*height), i*3); pDst[0] = pSrc[0]; //B pDst[1] = pSrc[1]; //G pDst[2] = pSrc[2]; //R } } cvFlip(mir, NULL, 0);// 0:上下镜像;1:左右镜像 // 准备最终结果图像 CvSize dstSize; dstSize.width = width; dstSize.height = height + mir_h; IplImage* dst = cvCreateImage(dstSize, src->depth, src->nChannels); cvZero(dst); // 载入源图像到结果图像中 cvSetImageROI(dst, cvRect(0, 0, width, height)); cvCopy(src, dst); cvResetImageROI(dst); // 准备镜像图像 IplImage* mask = cvCreateImage(cvSize(mir_w, mir_h), mir->depth, mir->nChannels); CvScalar a = CV_RGB(255, 255, 255); CvScalar b = CV_RGB(0, 0, 0); cvSet(mask, a); CvPoint origin = cvPoint(mir_w/2, 0); // 光源设在镜像图像上方 //CvPoint center = cvPoint(mir_w/2, mir_h/2); float distance = (mir_w-1 - origin.x)* (mir_w-1 - origin.x)+ // 光源与图像右下角的距离 (mir_h-1 - origin.y)* (mir_h-1 - origin.y); distance = sqrt(distance); //double weightB = (b.val[0] - a.val[0])/distance; // 分别计算BGR三个通道的权重 //double weightG = (b.val[1] - a.val[1])/distance; //double weightR = (b.val[2] - a.val[2])/distance; double weight = (b.val[0] - a.val[0])/distance; // 计算BGR三个通道的权重 -1.72 for ( int i=0; i<mask->width; i++) { for (int j=0; j<mask->height; j++) { float dist = WEIGHT*(j-origin.y)*(j-origin.y); dist = sqrt(dist); uchar* ptr = &CV_IMAGE_ELEM(mask, uchar, j, i*3); ptr[0] = cvRound(ptr[0] + weight*dist-DELTA); //B ptr[1] = cvRound(ptr[1] + weight*dist-DELTA); //G ptr[2] = cvRound(ptr[2] + weight*dist-DELTA); //R } } cvAddWeighted(mir,ALPHA , mask, BETA, 0, mir); // 载入镜像图像到结果图像中 cvSetImageROI(dst, cvRect(0, height, mir_w, mir_h)); cvCopy(mir, dst); cvResetImageROI(dst); cvNamedWindow( "test", 1); cvShowImage( "test", dst); cvWaitKey(); // 释放资源 cvDestroyWindow("test"); cvReleaseImage(&src); cvReleaseImage(&dst); cvReleaseImage(&mask); cvReleaseImage(&mir); return 0; }
运行结果如下:
参考: