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 << );
key ^= (key >> );
key += (key << );
key ^= (key >> );
key += ~(key << );
key ^= (key >> );
return key;
} static int fastRandomInt(int seed) {
int nseed = seed * +0XFFFFFFF;
return wang_inthash(nseed);
} static float fastRandom01(int seed)
{
return float(fastRandomInt(seed) % ) / 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 = )
{
// 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 = ;
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+);
auto fitvar = GLY_MATH::fit<float>(rd01,,,-,); // random move 1 pixel pos
point.rx() += fitvar*;
point.ry() += fitvar*;
}
}; }
// some function move points using namespace TopVertex; ImageParse::ImageParse(const QString &path):
mImagePath(path),
mScatterNum(){
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 = ;k<count;k++)
{
auto rd01 = GLY_MATH::fastRandom01(k);
auto numChoice = abs(int(rd01 * cont.size())-) ;
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 = ; ht < hdt; ht ++)
{
for(int wt = ; wt< wdt ; wt ++)
{
QColor rgb = QColor(mImage.pixel(wt,ht));
if (rgb.red()<=)
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 = ; ht < hdt; ht ++)
{
for (int wt = ; wt < wdt; wt++)
{
QColor rgb = QColor(mImage.pixel(wt, ht));
if (rgb.red() <= )
continue; if(rgb.red() >= && rgb.red()<)
{
part1.emplace_back(QPointF(wt,ht));
}
if(rgb.red() >= && rgb.red()<)
{
part2.emplace_back(QPointF(wt,ht));
}
if(rgb.red() >= && rgb.red()<)
{
part3.emplace_back(QPointF(wt,ht));
}
if(rgb.red() >= && rgb.red()<=)
{
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(,);
setMinimumSize(QSize(,)); mImageParse.loadImage("./gray4.jpg");
mImageParse.setScatterNum();
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 = ,
int maxSample=)
{
for(int i=;i<maxSample;i++)
{
auto alpha = (maxSample-i) * glowTint;
pen.setColor(QColor(,,,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(,,,));
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()),,iw,,ww);
auto newy = GLY_MATH::fit<float>(float(pf.y()),,ih,,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(); }

Simple scatter method in 2d picture(Qt)的更多相关文章

  1. 卡尔曼滤波—Simple Kalman Filter for 2D tracking with OpenCV

    之前有关卡尔曼滤波的例子都比较简单,只能用于简单的理解卡尔曼滤波的基本步骤.现在让我们来看看卡尔曼滤波在实际中到底能做些什么吧.这里有一个使用卡尔曼滤波在窗口内跟踪鼠标移动的例子,原作者主页:http ...

  2. 2D Rotated Rectangle Collision

    Introduction While working on a project for school, I found it necessary to perform a collision chec ...

  3. Image Processing and Analysis_15_Image Registration:HAIRIS: A Method for Automatic Image Registration Through Histogram-Based Image Segmentation——2011

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  4. Core Java Volume I — 4.5. Method Parameters

    4.5. Method ParametersLet us review the computer science terms that describe how parameters can be p ...

  5. 《Qt 实战一二三》

    简介 "我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流",不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的 ...

  6. 动态linq表达式新方法,Dynamic LINQ Extension Method

    Remember those old posts on Dynamic LINQ? You are probably aware that Microsoft has made its impleme ...

  7. JNI加载Native Library 以及 跨线程和Qt通信

    Part1 Java Native Interface-JNI-JAVA本地调用 JNI标准是Java平台的一部分, 允许Java代码和其他语言进行交互; 开始实现-> Step 1) 编写Ja ...

  8. Really simple SSH proxy (SOCKS5)

    原文: https://thomashunter.name/blog/really-simple-ssh-proxy-socks5/ SOCKS5 is a simple, eloquent meth ...

  9. qt quick中qml编程语言

    Qt QML 入门 — 使用C++定义QML类型 发表于 2013 年 3 月 11 日   注册C++类 注册可实例化的类型 注册不实例化的QML类型 附带属性 注册C++类 注册可实例化的类型 如 ...

随机推荐

  1. CentOS 7.0下使用yum安装MySQL

    CentOS7默认数据库是mariadb,配置等用着不习惯,因此决定改成mysql,但是CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1 ...

  2. python 操作 saltstack Api(二) 示例

    获取token #!/usr/bin/env python #-*-coding:utf--*- import urllib import urllib.parse import urllib.req ...

  3. GlusterFS分布式文件系统部署及基本使用(CentOS 7.6)

    GlusterFS分布式文件系统部署及基本使用(CentOS 7.6) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Gluster File System 是一款自由软件,主要由 ...

  4. Linux虚拟内存(swap)调优篇-“swappiness”,“vm.dirty_background_ratio”和“vm.dirty_ratio”

      Linux虚拟内存(swap)调优篇-“swappiness”,“vm.dirty_background_ratio”和“vm.dirty_ratio” 作者:尹正杰 版权声明:原创作品,谢绝转载 ...

  5. jdk和jvm基本介绍

    一.JDK和JRE? 在刚入门java开发的时候,第一步都要从官网下载JDK来帮助开发,下载下来安装之后看到安装目录结构如下 bin目录:存放Java的编译器.解释器等工具(可执行文件). db目录: ...

  6. [JUC-1]并发包实现及线程状态

    一.Java 并发包实现 二.Java 线程状态转换图

  7. 详解Linux内核红黑树算法的实现

    转自:https://blog.csdn.net/npy_lp/article/details/7420689 内核源码:linux-2.6.38.8.tar.bz2 关于二叉查找树的概念请参考博文& ...

  8. golang byte与rune区别

    先看代码 package main import ( "fmt" ) func main() { var a = "hello world" var b = & ...

  9. centos升级openssh版本

    似乎升级就是简单的安装ssh包就行了,没进行其他修改,虚拟机24个中高低漏洞解决 安装最新包: 1.下载:https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/por ...

  10. CSS魔法(五)项目实战

    三大标签--title.description.keyword   淘宝网 <title>淘宝网 - 淘!我喜欢</title> <meta name="spm ...