天天看點

opencv 實作圖像倒影(漸變)效果【源碼】

#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;
}      

運作結果如下:

opencv 實作圖像倒影(漸變)效果【源碼】

參考:

http://blog.csdn.net/willyang519/article/details/8179976 http://blog.csdn.net/quarryman/article/details/6418188

繼續閱讀