opencv漩涡效果

来源:互联网 发布:java 装饰者模式 编辑:程序博客网 时间:2024/04/27 19:33
cv::remap

基本思路转换为极坐标系,然后根据r给th一个偏移量,示例给的偏移量是 log(k*r+b)*log(k*r+b)

void valueChanged(double radius,double rate) {    this->setAlgorithm([rate_=rate,            radius,            this    ](const QImage &arg)->QImage {        if (rate_<.00000001) { return arg; }        if (radius<.00000001) { return arg; }        auto rate=1.0/rate_;        try {            cv::Mat inputMat(arg.height(),arg.width(),CV_8UC3,                const_cast<uchar*>(arg.constBits()),                arg.bytesPerLine());            /*copy the image*/            QImage ans={ arg.size(),arg.format() };            cv::Mat outputMat(                ans.height(),ans.width(),CV_8UC3,                const_cast<uchar*>(ans.constBits()),                ans.bytesPerLine()            );            cv::Mat mapX(ans.height(),ans.width(),CV_32FC1);            cv::Mat mapY(ans.height(),ans.width(),CV_32FC1);            using number_type=double;            const auto width=arg.width();            const auto height=arg.height();            const number_type center_x=width/2.;            const number_type center_y=height/2.;            /*(x,y)是变换后的点坐标*/            for (auto y=0; y<height; ++y) {                for (auto x=0; x<width; ++x) {                    auto dy=y-center_y;                    auto dx=x-center_x;                    /*不动点*/                    if ((dx==0)&&(dy==0)) {                        continue;                    }                    /*化为极坐标*/                    /*求出偏角*/                    auto th=std::atan2(dy,dx);                    /*求p*/                    auto dis=std::sqrt(dx*dx+dy*dy);                    if (dis>radius) {                        mapX.at<float>(y,x)=x;                        mapY.at<float>(y,x)=y;                        continue;                    }                    /*求出偏转角度*/                    {                        auto tmp=std::log(std::abs(dis*rate)+0.0001);                        tmp*=tmp;                        th+=tmp;                    }                    /*求出原来的坐标*/                    dx=dis*std::cos(th)+center_x;                    dy=dis*std::sin(th)+center_y;                    /*设置变换矩阵*/                    mapX.at<float>(y,x)=static_cast<float>(dx);                    mapY.at<float>(y,x)=static_cast<float>(dy);                }            }            cv::remap(inputMat,outputMat,mapX,mapY,                cv::INTER_LANCZOS4,                cv::BORDER_REPLICATE );            return std::move(ans);        }        catch (...) {            CPLUSPLUS_EXCEPTION(false);        }        return arg;    });}


0 0
原创粉丝点击