zoukankan      html  css  js  c++  java
  • Simple scatter method in 2d picture(Qt)

    Result:

     grayMap:

     

    MathTools:

    //
    // Created by Administrator on 2017/8/17.
    //
    
    #ifndef QTSCATTER_MATHTOOLS_H
    #define QTSCATTER_MATHTOOLS_H
    
    
    #include <string>
    #include <vector>
    #include <iostream>
    #include <sstream>
    using namespace std;
    
    namespace TopVertex
    {
        class GLY_MATH
        {
        public:
            template<typename T>
            static T min(T a, T b) {
                if (a > b) {
                    return b;
                } else {
                    return a;
                }
            }
    
            template<typename T>
            static T max(T a, T b) {
                if (a > b) {
                    return a;
                } else {
                    return b;
                }
            }
    
            template<typename T>
            static bool zero_compare(T a, double tol = 0.00001) {
                return a >= -tol && a <= tol;
            }
    
            // DO NOT USE THIS FIT TO FIT VECTOR VALUE
            template<typename T>
            static T fit(T var, T omin, T omax, T nmin, T nmax) {
                T d = omax - omin;
                if (zero_compare(d)) {
                    return (nmin + nmax) * 0.5;
                }
                if (omin < omax) {
                    if (var < omin) return nmin;
                    if (var > omax) return nmax;
                } else {
                    if (var < omax) return nmax;
                    if (var > omin) return nmin;
                }
                return nmin + (nmax - nmin) * (var - omin) / d;
            }
    
            //return -1 to 1
            template<typename T>
            static T fit_negate(T var, T omin, T omax) {
                return fit(var, omin, omax, -1.0, 1.0);
            }
    
    
            //string split
            static std::vector<std::string> split_string(std::string &inputString, char &split_char) {
                std::stringstream ss(inputString);
                std::string sub_str;
                std::vector<std::string> sp_strPath;
                sp_strPath.clear();
                while (getline(ss, sub_str, split_char)) {
                    sp_strPath.push_back(sub_str);
                }
                return sp_strPath;
            }
    
            //value to string
            template<typename T>
            // T must be a value int/float/double
            static std::string value_to_str(T &value) {
                std::ostringstream os;
                os << value;
                return os.str();
            }
    
    
            static int wang_inthash(int key) {
                // From http://www.concentric.net/~Ttwang/tech/inthash.htm
                key += ~(key << 16);
                key ^= (key >> 5);
                key += (key << 3);
                key ^= (key >> 13);
                key += ~(key << 9);
                key ^= (key >> 17);
                return key;
            }
    
            static int fastRandomInt(int seed) {
                int nseed = seed * 1664525+0XFFFFFFF;
                return wang_inthash(nseed);
            }
    
            static float fastRandom01(int seed)
            {
                return float(fastRandomInt(seed) % 1000000) / 1000000.0f;
            }
    
        };
    }
    
    
    
    #endif //QTSCATTER_MATHTOOLS_H
    MathTools

    点位移类,用于后续动画

    //
    // Created by Administrator on 2017/8/18.
    //
    
    #ifndef QTSCATTER_POINTMOTION_H
    #define QTSCATTER_POINTMOTION_H
    
    namespace TopVertex
    {
    
        // our default motion
        template <typename T>
        class PolicyMotion
        {
        public:
    
            template <typename addVal>
            static void advect(T &point,const addVal &val,int loopId = 0)
            {
                // not implement
            }
        };
    
        // per step motion
        template <typename opType=int,
                template <typename> class Policy = PolicyMotion>
        class Motion
        {
        public:
            template <typename T>
            static void advect_motion(T begin, T end,float time)
            {
                int loopId = 0;
                while(begin!= end)
                {
                    Policy<opType>::advect(*begin,time,loopId);
                    begin++;
                    loopId++;
                }
            }
    
        };
    
    }
    
    
    #endif //QTSCATTER_POINTMOTION_H
    PointMotion.h

    QImage分析像素:

    //
    // Created by Administrator on 2017/8/17.
    //
    
    #ifndef QTSCATTER_IMAGEPARSE_H
    #define QTSCATTER_IMAGEPARSE_H
    
    #include <QImage>
    #include <QString>
    #include <QPointF>
    #include <QVector>
    #include <QDebug>
    #include <vector>
    
    
    
    
    namespace TopVertex
    {
        class ImageParse
        {
        public:
            enum PARSETYPE{UNIFORM=0x00,STEP=0x01};
    
            ImageParse() = default;
    
            explicit ImageParse(const QString &path);
    
            ImageParse(const QString &path,const int &ScatterNum);
    
            // parse image to data
            void parse(PARSETYPE parseFlag=UNIFORM);
    
            // our pixels positions
            std::vector<QPointF> &getParsePixelsPos();
    
    
            // load image
            inline void loadImage(const QString &path) {
                if(!mImage.load(path))
                    qDebug() << "Image load " << path << " error";
            }
    
            // set scatter num
            inline void setScatterNum(int pts) {
                mScatterNum = pts;
            }
    
            // get image
            QImage &getImage(){return mImage;}
    
        private:
            // Store image to parse
            QImage mImage;
    
            void parseUniform();
            void parseStep();
    
        private:
            // store our data in here
            std::vector<QPointF> mPixelsPos;
    
            // read Image path
            QString mImagePath;
    
            // scatter counts
            int mScatterNum;
    
    
        };
    }
    
    
    
    #endif //QTSCATTER_IMAGEPARSE_H
    ImageParse.h
    //
    // Created by Administrator on 2017/8/17.
    //
    
    #include "ImageParse.h"
    #include <QDebug>
    #include <QColor>
    #include <algorithm>
    #include "MathTools.h"
    #include "PointMotion.h"
    
    
    
    // some function move points
    namespace TopVertex
    {
    
        // our default motion
        template <typename T>
        class randomMotion
        {
        public:
            template <typename addVal>
            static void advect(T &point,const addVal &val,int loopId)
            {
                auto rd01   = GLY_MATH::fastRandom01(loopId+1000);
                auto fitvar = GLY_MATH::fit<float>(rd01,0,1,-1,1); // random move 1 pixel pos
                point.rx() += fitvar*2;
                point.ry() += fitvar*2;
            }
        };
    
    }
    // some function move points
    
    using namespace TopVertex;
    
    ImageParse::ImageParse(const QString &path):
            mImagePath(path),
            mScatterNum(0){
        loadImage(path);
    
    }
    ImageParse::ImageParse(const QString &path,const int &ScatterNum):
            mImagePath(path),
            mScatterNum(ScatterNum){
        loadImage(path);
    
    }
    
    std::vector<QPointF> & ImageParse::getParsePixelsPos()
    {
        return mPixelsPos;
    }
    
    
    void ImageParse::parse(PARSETYPE parseFlag)
    {
        if(parseFlag == UNIFORM)
            parseUniform();
        else
            parseStep();
    
    }
    
    
    
    template <typename T>
    static void RandomSelectByCount(int count, T &cont, T &desCont)
    {
        for(int k = 0;k<count;k++)
        {
            auto rd01 = GLY_MATH::fastRandom01(k);
            auto numChoice = abs(int(rd01 * cont.size())-1) ;
            desCont.emplace_back(cont[numChoice]);
        }
    }
    
    void ImageParse::parseUniform() {
        qDebug() << "w/h:"<<mImage.width() << " "<< mImage.height() ;
        auto wdt = mImage.width();
        auto hdt = mImage.height();
        vector<QPointF> storePos;
        for(int ht = 0 ; ht < hdt; ht ++)
        {
            for(int wt = 0; wt< wdt ; wt ++)
            {
                QColor rgb = QColor(mImage.pixel(wt,ht));
                if (rgb.red()<=10)
                    continue;
                storePos.emplace_back(QPointF(wt,ht));
    
            }
        }
        RandomSelectByCount(mScatterNum,storePos,mPixelsPos);
        Motion<QPointF,randomMotion>::advect_motion(mPixelsPos.begin(),mPixelsPos.end(),0.0);
    }
    
    
    
    void ImageParse::parseStep()
    {
    
    
        auto wdt = mImage.width();
        auto hdt = mImage.height();
    
    
        int count_10_50   = floor(mScatterNum * 0.10);
        int count_50_100  = floor(mScatterNum * 0.15);
        int count_100_200 = floor(mScatterNum * 0.35);
        int count_200_255 = floor(mScatterNum * 0.45);
    
    
        qDebug() << "10-50   " << count_10_50;
        qDebug() << "50-100  " << count_50_100;
        qDebug() << "100-200 " << count_100_200;
        qDebug() << "200-255 " << count_200_255;
    
    
        vector<QPointF> part1;
        vector<QPointF> part2;
        vector<QPointF> part3;
        vector<QPointF> part4;
    
        for(int ht = 0 ; ht < hdt; ht ++)
        {
            for (int wt = 0; wt < wdt; wt++)
            {
                QColor rgb = QColor(mImage.pixel(wt, ht));
                if (rgb.red() <= 10)
                    continue;
    
                if(rgb.red() >=11 && rgb.red()<50)
                {
                    part1.emplace_back(QPointF(wt,ht));
                }
                if(rgb.red() >=50 && rgb.red()<100)
                {
                    part2.emplace_back(QPointF(wt,ht));
                }
                if(rgb.red() >=100 && rgb.red()<200)
                {
                    part3.emplace_back(QPointF(wt,ht));
                }
                if(rgb.red() >=200 && rgb.red()<=255)
                {
                    part4.emplace_back(QPointF(wt,ht));
                }
    
    
            }
        }
    
        RandomSelectByCount(count_10_50, part1, mPixelsPos);
        RandomSelectByCount(count_50_100, part2, mPixelsPos);
        RandomSelectByCount(count_100_200, part3, mPixelsPos);
        RandomSelectByCount(count_200_255, part4, mPixelsPos);
        // random move points
        Motion<QPointF,randomMotion>::advect_motion(mPixelsPos.begin(),mPixelsPos.end(),0.0);
    
    }
    ImageParse.cpp

    显示窗口:

    //
    // Created by Administrator on 2017/8/17.
    //
    
    #ifndef QTSCATTER_VIDEOWIDGET_H
    #define QTSCATTER_VIDEOWIDGET_H
    
    #include <QWidget>
    #include "ImageParse.h"
    #include <QResizeEvent>
    
    namespace  TopVertex
    {
        class VideoWidget:public QWidget
        {
            Q_OBJECT
        public:
    
    
    
            explicit VideoWidget(QWidget *parent = nullptr):QWidget(parent)
            {
                resize(1280,720);
                setMinimumSize(QSize(50,50));
    
    
                mImageParse.loadImage("./gray4.jpg");
                mImageParse.setScatterNum(1000);
                mImageParse.parse(ImageParse::STEP);
    
    
                // mainwindow background picture
                mBgImage.load("./dp.jpg");
    
    
                mInitW = width();
                mInitH = height();
            }
        private:
            ImageParse mImageParse;
            int mInitW;
            int mInitH;
            QImage mBgImage;
        protected:
            void paintEvent(QPaintEvent *e) override ;
            void resizeEvent(QResizeEvent *e) override;
    
        };
    
    
    }
    
    
    #endif //QTSCATTER_VIDEOWIDGET_H
    VideoWidget.h
    //
    // Created by Administrator on 2017/8/17.
    //
    
    #include "VideoWidget.h"
    #include <algorithm>
    #include "MathTools.h"
    using namespace TopVertex;
    #include <QPainter>
    using namespace std;
    
    
    template <typename T>
    static void paintGlow(QPainter &painter,
                          QPen &pen,
                          T &cont,
                          float glowRadius = 1.2,
                          float glowTint = 1,
                          int maxSample=10)
    {
        for(int i=0;i<maxSample;i++)
        {
            auto alpha = (maxSample-i) * glowTint;
            pen.setColor(QColor(255,0,0,alpha));
            pen.setWidthF(i * glowRadius);
            painter.setPen(pen);
            auto iter = cont.begin();
            for_each(iter,cont.end(),[&painter](const QPointF&pf){painter.drawPoint(pf);});
        }
    }
    
    
    
    void VideoWidget::paintEvent(QPaintEvent *e)
    {
        QPainter painter(this);
        painter.drawImage(this->rect(),mBgImage);
        painter.setRenderHint(QPainter::HighQualityAntialiasing);
    
        QPen pen(QColor(255,0,0,255));
        pen.setWidthF(1.0);
        painter.setBrush(Qt::blue);
        painter.setPen(pen);
        auto &pos = mImageParse.getParsePixelsPos();
        auto iter = pos.begin();
        for_each(iter,pos.end(),[&painter](const QPointF&pf){painter.drawPoint(pf);});
        paintGlow(painter,pen,mImageParse.getParsePixelsPos());
    
    }
    void VideoWidget::resizeEvent(QResizeEvent *e)
    {
        // orig image width height
        auto iw = mInitW;
        auto ih = mInitH;
        // current width and height
        auto ww = this->width();
        auto wh = this->height();
        auto &pos = mImageParse.getParsePixelsPos();
        auto iter = pos.begin();
        auto resize = [&ww,&wh,&iw,&ih](QPointF&pf)
        {
            auto newx = GLY_MATH::fit<float>(float(pf.x()),0,iw,0,ww);
            auto newy = GLY_MATH::fit<float>(float(pf.y()),0,ih,0,wh);
    
            pf.rx() = newx;
            pf.ry() = newy;
        };
        for_each(iter,pos.end(),resize);
        mInitW = width();
        mInitH = height();
    
    }
    VideoWidget.cpp

     main.cpp

    #include <QApplication>
    #include "ImageParse.h"
    #include <QDebug>
    #include "VideoWidget.h"
    
    using namespace TopVertex;
    
    int main(int argc, char *argv[])
    {
        
        QApplication a(argc, argv);
        VideoWidget w;
        w.show();
        return a.exec();
        
    
    }
    View Code
  • 相关阅读:
    leetcode刷题笔记三十九 组合总和
    leetcode刷题笔记三十八 外观数列
    leetcode刷题笔记三十七 解数独
    leetcode刷题笔记三十六 有效的数独
    HTML5每日一练之input新增加的六种时间类型应用
    HTML5每日一练之input新增加的5种其他类型1种标签应用
    html5+css3中的background: -moz-linear-gradient 用法
    HTML5新标签解释及用法
    让IE浏览器支持CSS3圆角的方法
    纯CSS3实现的图片滑块程序,效果非常酷
  • 原文地址:https://www.cnblogs.com/gearslogy/p/7395818.html
Copyright © 2011-2022 走看看