mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-14 08:34:37 +00:00
Added Watermarking filter
This commit is contained in:
parent
353d60c33f
commit
e75c4bd820
107
src/plugins_experimental/filter_watermark/ERF.h
Normal file
107
src/plugins_experimental/filter_watermark/ERF.h
Normal file
@ -0,0 +1,107 @@
|
||||
#include <iostream>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
template<class T>
|
||||
inline T SQR(const T a) {return a*a;}
|
||||
|
||||
|
||||
struct Erf {
|
||||
static const int ncof=28;
|
||||
static const double cof[28];
|
||||
|
||||
|
||||
inline double erf(double x) {
|
||||
if (x >=0.) return 1.0 - erfccheb(x);
|
||||
else return erfccheb(-x) - 1.0;
|
||||
}
|
||||
|
||||
inline double erfc(double x) {
|
||||
if (x >= 0.) return erfccheb(x);
|
||||
else return 2.0 - erfccheb(-x);
|
||||
}
|
||||
|
||||
double erfccheb(double z){
|
||||
int j;
|
||||
double t,ty,tmp,d=0.,dd=0.;
|
||||
if (z < 0.) throw("erfccheb requires nonnegative argument");
|
||||
t = 2./(2.+z);
|
||||
ty = 4.*t - 2.;
|
||||
for (j=ncof-1;j>0;j--) {
|
||||
tmp = d;
|
||||
d = ty*d - dd + cof[j];
|
||||
dd = tmp;
|
||||
}
|
||||
return t*exp(-z*z + 0.5*(cof[0] + ty*d) - dd);
|
||||
}
|
||||
|
||||
double inverfc(double p) {
|
||||
double x,err,t,pp;
|
||||
if (p >= 2.0) return -100.;
|
||||
if (p <= 0.0) return 100.;
|
||||
pp = (p < 1.0)? p : 2. - p;
|
||||
t = sqrt(-2.*log(pp/2.));
|
||||
x = -0.70711*((2.30753+t*0.27061)/(1.+t*(0.99229+t*0.04481)) - t);
|
||||
for (int j=0;j<2;j++) {
|
||||
err = erfc(x) - pp;
|
||||
x += err/(1.12837916709551257*exp(-SQR(x))-x*err);
|
||||
}
|
||||
return (p < 1.0? x : -x);
|
||||
}
|
||||
|
||||
inline double inverf(double p) {return inverfc(1.-p);}
|
||||
|
||||
};
|
||||
|
||||
const double Erf::cof[28] = {-1.3026537197817094, 6.4196979235649026e-1,
|
||||
1.9476473204185836e-2,-9.561514786808631e-3,-9.46595344482036e-4,
|
||||
3.66839497852761e-4,4.2523324806907e-5,-2.0278578112534e-5,
|
||||
-1.624290004647e-6,1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,
|
||||
6.529054439e-9,5.059343495e-9,-9.91364156e-10,-2.27365122e-10,
|
||||
9.6467911e-11, 2.394038e-12,-6.886027e-12,8.94487e-13, 3.13092e-13,
|
||||
-1.12708e-13,3.81e-16,7.106e-15,-1.523e-15,-9.4e-17,1.21e-16,-2.8e-17};
|
||||
double erfcc(const double x)
|
||||
{
|
||||
double t,z=fabs(x),ans;
|
||||
t=2./(2.+z);
|
||||
ans=t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
|
||||
t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
|
||||
t*(-0.82215223+t*0.17087277)))))))));
|
||||
return (x >= 0.0 ? ans : 2.0-ans);
|
||||
}
|
||||
struct Normaldist : Erf {
|
||||
double mu, sig;
|
||||
Normaldist(double mmu = 0., double ssig = 1.) : mu(mmu), sig(ssig) {
|
||||
if (sig <= 0.) throw("bad sig in Normaldist");
|
||||
}
|
||||
double p(double x) {
|
||||
return (0.398942280401432678/sig)*exp(-0.5*SQR((x-mu)/sig));
|
||||
}
|
||||
double cdf(double x) {
|
||||
return 0.5*erfc(-0.707106781186547524*(x-mu)/sig);
|
||||
}
|
||||
double invcdf(double p) {
|
||||
if (p <= 0. || p >= 1.) throw("bad p in Normaldist");
|
||||
return -1.41421356237309505*sig*inverfc(2.*p)+mu;
|
||||
}
|
||||
};
|
||||
struct Lognormaldist : Erf {
|
||||
double mu, sig;
|
||||
Lognormaldist(double mmu = 0., double ssig = 1.) : mu(mmu), sig(ssig) {
|
||||
if (sig <= 0.) throw("bad sig in Lognormaldist");
|
||||
}
|
||||
double p(double x) {
|
||||
if (x < 0.) throw("bad x in Lognormaldist");
|
||||
if (x == 0.) return 0.;
|
||||
return (0.398942280401432678/(sig*x))*exp(-0.5*SQR((log(x)-mu)/sig));
|
||||
}
|
||||
double cdf(double x) {
|
||||
if (x < 0.) throw("bad x in Lognormaldist");
|
||||
if (x == 0.) return 0.;
|
||||
return 0.5*erfc(-0.707106781186547524*(log(x)-mu)/sig);
|
||||
}
|
||||
double invcdf(double p) {
|
||||
if (p <= 0. || p >= 1.) throw("bad p in Lognormaldist");
|
||||
return exp(-1.41421356237309505*sig*inverfc(2.*p)+mu);
|
||||
}
|
||||
};
|
||||
286
src/plugins_experimental/filter_watermark/filter_watermark.cpp
Normal file
286
src/plugins_experimental/filter_watermark/filter_watermark.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "filter_watermark.h"
|
||||
#include "utilsWatermark.h"
|
||||
#include <QtScript>
|
||||
|
||||
|
||||
using namespace vcg;
|
||||
using namespace std;
|
||||
|
||||
|
||||
// Constructor usually performs only two simple tasks of filling the two lists
|
||||
// - typeList: with all the possible id of the filtering actions
|
||||
// - actionList with the corresponding actions. If you want to add icons to your filtering actions you can do here by construction the QActions accordingly
|
||||
|
||||
WatermarkPlugin::WatermarkPlugin()
|
||||
{
|
||||
typeList << FP_EMBED_WATERMARK << FP_DECODE_WATERMARK;
|
||||
|
||||
foreach(FilterIDType tt , types())
|
||||
actionList << new QAction(filterName(tt), this);
|
||||
}
|
||||
|
||||
// ST() must return the very short string describing each filtering action
|
||||
// (this string is used also to define the menu entry)
|
||||
QString WatermarkPlugin::filterName(FilterIDType filterId) const
|
||||
{
|
||||
switch(filterId) {
|
||||
case FP_EMBED_WATERMARK : return QString("Watermark embedding on 3D points");
|
||||
case FP_DECODE_WATERMARK : return QString("Watermark decoding on 3D points");
|
||||
default : assert(0);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Info() must return the longer string describing each filtering action
|
||||
// (this string is used in the About plugin dialog)
|
||||
QString WatermarkPlugin::filterInfo(FilterIDType filterId) const
|
||||
{
|
||||
switch(filterId) {
|
||||
case FP_EMBED_WATERMARK : return QString("Embed a watermark on the model with a given strength depending on a string code. The string code can be a mix of letters, numbers and special characters. A missing alarm probability is guaranteed according to a prefixed false alarm probability.<br> See: <br /> <i>F. Uccheddu, M. Corsini and M. Barni </i><br/> <b>Wavelet-Based Blind Watermarking of 3D Models</b><br/>ACM Multimedia and Security Workshop, 2004, pp. 143-154.<br/><br>");
|
||||
case FP_DECODE_WATERMARK : return QString("Decode a watermark potentially embedded on the model and depending on a string code. The string code is a mix of letters, numbers and special characters.");
|
||||
default : assert(0);
|
||||
}
|
||||
return QString("Unknown Filter");
|
||||
}
|
||||
|
||||
// The FilterClass describes in which generic class of filters it fits.
|
||||
// This choice affect the submenu in which each filter will be placed
|
||||
// More than a single class can be choosen.
|
||||
WatermarkPlugin::FilterClass WatermarkPlugin::getClass(QAction *a)
|
||||
{
|
||||
switch(ID(a))
|
||||
{
|
||||
case FP_EMBED_WATERMARK : return MeshFilterInterface::Smoothing;
|
||||
case FP_DECODE_WATERMARK : return MeshFilterInterface::Smoothing;
|
||||
default : assert(0);
|
||||
}
|
||||
return MeshFilterInterface::Generic;
|
||||
}
|
||||
|
||||
// This function define the needed parameters for each filter. Return true if the filter has some parameters
|
||||
// it is called every time, so you can set the default value of parameters according to the mesh
|
||||
// For each parameter you need to define,
|
||||
// - the name of the parameter,
|
||||
// - the string shown in the dialog
|
||||
// - the default value
|
||||
// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog)
|
||||
void WatermarkPlugin::initParameterSet(QAction *action,MeshModel &m, RichParameterSet & parlst)
|
||||
{
|
||||
switch(ID(action)) {
|
||||
case FP_EMBED_WATERMARK :
|
||||
case FP_DECODE_WATERMARK :
|
||||
parlst.addParam(new RichFloat("Power_gamma",(float)0.001,"Power value","Power value for the watermark; trade-off between visual quality and robustness. The default is 0.001"));
|
||||
parlst.addParam(new RichString("String_code","STRING_CODE", "Embedding code","The code to embed into the model. It can be an alphanumeric string"));
|
||||
break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// The Real Core Function doing the actual mesh processing.
|
||||
// Move Vertex of a random quantity
|
||||
bool WatermarkPlugin::applyFilter(QAction * filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
|
||||
{
|
||||
|
||||
MeshModel &m=*md.mm();
|
||||
const float max_gamma = par.getFloat("Power_gamma");
|
||||
const QString string_code = par.getString("String_code");
|
||||
|
||||
utilsWatermark utilw;
|
||||
double cellTablesize = 1.0;
|
||||
int nsTheta = 360.0/cellTablesize;
|
||||
int nsPhi = 180.0/cellTablesize;
|
||||
|
||||
unsigned int seed = utilw.ComputeSeed(string_code);
|
||||
|
||||
vector<vector<double> > watermarkTable = utilw.CreateWatermarkTable(seed);
|
||||
|
||||
switch(ID(filter))
|
||||
{
|
||||
case FP_EMBED_WATERMARK:
|
||||
{
|
||||
int indexThetaRef,indexPhiRef;
|
||||
|
||||
double DELTAR;
|
||||
|
||||
//for(unsigned int i = 0; i< m.cm.vert.size(); i++)
|
||||
for(CMeshO::VertexIterator vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi)
|
||||
{
|
||||
double sphR,sphTheta,sphPhi;
|
||||
|
||||
double dx = (vi)->P()[0];
|
||||
double dy = (vi)->P()[1];
|
||||
double dz = (vi)->P()[2];
|
||||
|
||||
// Passo 1 : Trasformazione in coordinate sferiche della wavelet
|
||||
utilw.cartesian2sph( vi->P()[0], vi->P()[1],vi->P()[2], sphR, sphTheta, sphPhi );
|
||||
|
||||
// Può accadere, basta pensare al vertice (-1.0,0.0,0.0)
|
||||
if ( (sphTheta+180.0) >= 360.0)
|
||||
sphTheta -= 360.0;
|
||||
|
||||
double dd = PHIEXCLUSION_DEGREE;
|
||||
if ((sphR > 0.000000000001)&&(sphPhi < 180.0-PHIEXCLUSION_DEGREE)&&(sphPhi > PHIEXCLUSION_DEGREE))
|
||||
{
|
||||
// Passo 2 : Mappatura sul Tabella
|
||||
|
||||
nsPhi = 180.0/cellTablesize;
|
||||
nsTheta = 360.0/cellTablesize;
|
||||
|
||||
indexThetaRef = (int)utilw.round( (sphTheta+180.0) );
|
||||
indexPhiRef = (int)utilw.round( (179.0/180.0)*sphPhi );
|
||||
|
||||
if (indexThetaRef == nsTheta)
|
||||
indexThetaRef = 0;
|
||||
|
||||
DELTAR = watermarkTable[indexPhiRef][indexThetaRef];
|
||||
|
||||
//watermark on vertex module
|
||||
sphR = sphR + DELTAR*max_gamma;
|
||||
|
||||
if (sphR < 0.00000000001)
|
||||
sphR = 0.00000000001;
|
||||
|
||||
utilw.sph2cartesian( sphR,sphTheta,sphPhi, (vi)->P()[0], (vi)->P()[1], (vi)->P()[2] );
|
||||
double dx = (vi)->P()[0];
|
||||
double dy = (vi)->P()[1];
|
||||
double dz = (vi)->P()[2];
|
||||
|
||||
int dd=0;
|
||||
}
|
||||
|
||||
}
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(m.cm);
|
||||
|
||||
|
||||
} break;
|
||||
case FP_DECODE_WATERMARK:
|
||||
{
|
||||
double Pf = 0.01;
|
||||
double Pm;
|
||||
|
||||
double sphR,sphTheta,sphPhi;
|
||||
|
||||
int indexThetaRef,indexPhiRef;
|
||||
|
||||
double DELTAR;
|
||||
|
||||
vector<double> corr;
|
||||
vector<double> sphRi;
|
||||
|
||||
int n=0;
|
||||
|
||||
for(CMeshO::VertexIterator vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi)
|
||||
{
|
||||
|
||||
// Passo 1 : Trasformazione in coordinate sferiche della wavelet
|
||||
utilw.cartesian2sph( vi->P()[0], vi->P()[1],vi->P()[2], sphR, sphTheta, sphPhi );
|
||||
|
||||
// Può accadere, basta pensare al vertice (-1.0,0.0,0.0)
|
||||
if ( (sphTheta+180.0) >= 360.0)
|
||||
sphTheta -= 360.0;
|
||||
|
||||
if ((sphR > 0.000000000001)&&(sphPhi < 180.0-PHIEXCLUSION_DEGREE)&&(sphPhi > PHIEXCLUSION_DEGREE))
|
||||
{
|
||||
nsPhi = 180.0/cellTablesize;
|
||||
nsTheta = 360.0/cellTablesize;
|
||||
|
||||
indexThetaRef = (int)utilw.round( (sphTheta+180.0) );
|
||||
indexPhiRef = (int)utilw.round( (179.0/180.0)*sphPhi );
|
||||
|
||||
if (indexThetaRef == nsTheta)
|
||||
indexThetaRef = 0;
|
||||
|
||||
DELTAR = watermarkTable[indexPhiRef][indexThetaRef];
|
||||
|
||||
sphRi.push_back( sphR );
|
||||
corr.push_back(sphR*DELTAR);
|
||||
n++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
double mean_corr = 0;
|
||||
double var_corr = 0;
|
||||
|
||||
// mean
|
||||
for(int i = 0; i < n; i++)
|
||||
mean_corr += corr[i];
|
||||
mean_corr /= (double)n;
|
||||
|
||||
|
||||
// variance
|
||||
for(int i = 0; i < n; i++)
|
||||
var_corr+= pow(corr[i] - mean_corr, 2);
|
||||
var_corr /= (double)n;
|
||||
|
||||
|
||||
//VALORI TEORICI
|
||||
double muRhoH0,muRhoH1;
|
||||
double varRhoH0, varRhoH1;
|
||||
double var_sphR = 0.0;
|
||||
for (int i=0; i<n; i++)
|
||||
var_sphR += pow(sphRi[i],2);
|
||||
var_sphR /= (double)n;
|
||||
|
||||
double b = RANGE_MARCHIO;
|
||||
|
||||
muRhoH0 = 0.0;
|
||||
varRhoH0 = (((b*b)/3.0)*var_sphR)/(double)(n-1);
|
||||
|
||||
muRhoH1 = max_gamma*((b*b)/3.0)/(double)(n);
|
||||
varRhoH1 = ((b*b)/3.0)/(double)(n-1)*(var_sphR+pow(max_gamma,2)*b*b/(double)(3*n));
|
||||
|
||||
double threshold = utilw.thresholdRo( muRhoH0, varRhoH0, muRhoH1, varRhoH1, Pf, Pm );
|
||||
|
||||
if (mean_corr <= threshold){
|
||||
errorMessage = "The mesh is NOT watermarked"; //
|
||||
return false;
|
||||
}
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(m.cm);
|
||||
} break;
|
||||
default : assert(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString WatermarkPlugin::filterScriptFunctionName( FilterIDType filterID )
|
||||
{
|
||||
switch(filterID) {
|
||||
case FP_EMBED_WATERMARK : return QString("embedWatermarking");
|
||||
case FP_DECODE_WATERMARK : return QString("decodeWatermarking");
|
||||
default : assert(0);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(WatermarkPlugin)
|
||||
57
src/plugins_experimental/filter_watermark/filter_watermark.h
Normal file
57
src/plugins_experimental/filter_watermark/filter_watermark.h
Normal file
@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef WATERMARKPLUGIN_H
|
||||
#define WATERMARKPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <common/interfaces.h>
|
||||
class QScriptEngine;
|
||||
|
||||
class WatermarkPlugin : public QObject, public MeshFilterInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MeshFilterInterface)
|
||||
|
||||
public:
|
||||
enum { FP_EMBED_WATERMARK, FP_DECODE_WATERMARK } ;
|
||||
|
||||
WatermarkPlugin();
|
||||
~WatermarkPlugin(){};
|
||||
|
||||
virtual QString pluginName(void) const { return "WatermarkPlugin"; }
|
||||
|
||||
virtual QString filterName(FilterIDType filter) const;
|
||||
virtual QString filterInfo(FilterIDType filter) const;
|
||||
virtual void initParameterSet(QAction *,MeshModel &/*m*/, RichParameterSet & /*parent*/);
|
||||
virtual bool applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & /*parent*/, vcg::CallBackPos * cb) ;
|
||||
virtual int postCondition( QAction* ) const {return MeshModel::MM_VERTCOORD | MeshModel::MM_FACENORMAL | MeshModel::MM_VERTNORMAL;};
|
||||
virtual FilterClass getClass(QAction *a);
|
||||
virtual QString filterScriptFunctionName(FilterIDType filterID);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,9 @@
|
||||
include (../../shared.pri)
|
||||
|
||||
HEADERS += filter_watermark.h \
|
||||
utilsWatermark.h
|
||||
|
||||
SOURCES += filter_watermark.cpp \
|
||||
utilsWatermark.cpp
|
||||
|
||||
TARGET = filter_watermark
|
||||
142
src/plugins_experimental/filter_watermark/utilsWatermark.cpp
Normal file
142
src/plugins_experimental/filter_watermark/utilsWatermark.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "utilsWatermark.h"
|
||||
#include "qstring.h"
|
||||
#include "filter_watermark.h"
|
||||
#include "ERF.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Seed generator for the psedo random sequence in the watermark table
|
||||
// The seed is obtained by multiplying the ascii codes of each char of the chosen string
|
||||
unsigned int utilsWatermark::ComputeSeed( QString string_code )
|
||||
{
|
||||
unsigned int code = (unsigned int)(string_code[0].digitValue());
|
||||
|
||||
for (int i=1; i<string_code.length(); i++)
|
||||
{
|
||||
code *= (unsigned int)(string_code[i].digitValue());
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
vector< vector<double> > utilsWatermark::CreateWatermarkTable(unsigned int seed)
|
||||
{
|
||||
|
||||
|
||||
double cellTablesize = 1.0;
|
||||
static vcg::math::MarsenneTwisterRNG rnd;
|
||||
rnd.initialize(seed);
|
||||
double p = 0; // I valori generati di 'p' vanno da -RANGE_MARCHIO a RANGE_MARCHIO
|
||||
|
||||
int nsTheta = 360.0/cellTablesize;
|
||||
int nsPhi = 180.0/cellTablesize;
|
||||
|
||||
vector<vector<double> > watermarkTable;
|
||||
watermarkTable.resize(nsPhi);
|
||||
for (int k = 0; k < nsPhi; ++k)
|
||||
watermarkTable[k].resize(nsTheta);
|
||||
|
||||
|
||||
int i,j;
|
||||
for (i=0; i<nsPhi; i++)
|
||||
{
|
||||
for (j=0; j<nsTheta; j++)
|
||||
{
|
||||
p = 2.0*(rnd.generate01())*RANGE_MARCHIO - RANGE_MARCHIO;
|
||||
watermarkTable[i][j] = p;
|
||||
}
|
||||
}
|
||||
|
||||
return watermarkTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Spheric to Cartesian Coordinates System conversion
|
||||
void utilsWatermark::sph2cartesian(double R, double theta, double phi, float &x, float &y, float &z)
|
||||
{
|
||||
// Conversione Gradi --> Radianti
|
||||
phi *= DEG_TO_RAD;
|
||||
theta *= DEG_TO_RAD;
|
||||
|
||||
x = float(R*cos(theta)*sin(phi));
|
||||
z = float(R*sin(theta)*sin(phi));
|
||||
y = float(R*cos(phi));
|
||||
|
||||
}
|
||||
|
||||
// Cartesian to Spheric Coordinates System conversion
|
||||
void utilsWatermark::cartesian2sph(double x, double y, double z, double &R, double &theta, double &phi)
|
||||
{
|
||||
R = sqrt( x*x + y*y + z*z );
|
||||
theta = atan2( z,x );
|
||||
phi = acos( y / R );
|
||||
|
||||
// Conversione Radianti --> Gradi
|
||||
phi *= RAD_TO_DEG;
|
||||
theta *= RAD_TO_DEG;
|
||||
}
|
||||
|
||||
// rounding
|
||||
double utilsWatermark::round(double x)
|
||||
{
|
||||
double app = floor(x);
|
||||
|
||||
if (x - app >= 0.5)
|
||||
return (app + 1.0);
|
||||
else
|
||||
return app;
|
||||
}
|
||||
|
||||
// evaluate threshold
|
||||
double utilsWatermark::thresholdRo(double muRhoH0, double varRhoH0,
|
||||
double muRhoH1, double varRhoH1,
|
||||
double Pf, double &Pm)
|
||||
{
|
||||
|
||||
Erf erf;
|
||||
double Y;
|
||||
double Z;
|
||||
|
||||
// Calcolo di T(ro)
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
Y = erf.inverfc( 2.0*Pf );
|
||||
|
||||
double Trho = sqrt(2.0*varRhoH0)*Y + muRhoH0;
|
||||
|
||||
// Calcolo di Pm
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
//Z = gsl_sf_erfc( sqrt( ((muRhoH1 - Trho)*(muRhoH1 - Trho))/(2.0*varRhoH1)) );
|
||||
//Z = erfc( sqrt( ((muRhoH1 - Trho)*(muRhoH1 - Trho))/(2.0*varRhoH1)) );
|
||||
Z = erf.erfc( sqrt( ((muRhoH1 - Trho)*(muRhoH1 - Trho))/(2.0*varRhoH1)) );
|
||||
|
||||
Pm = 0.5*Z;
|
||||
|
||||
return Trho;
|
||||
}
|
||||
51
src/plugins_experimental/filter_watermark/utilsWatermark.h
Normal file
51
src/plugins_experimental/filter_watermark/utilsWatermark.h
Normal file
@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __UTILS_WATERMARKPLUGIN_H
|
||||
#define __UTILS_WATERMARKPLUGIN_H
|
||||
|
||||
#define RANGE_MARCHIO 1.0 // I valori della TabellaMarchio vanno da -RANGE_MARCHIO a +RANGE_MARCHIO (distribuiti UNIFORMEMENTE)
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105 // Radianti*RAD_TO_DEG = Gradi
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886 // Gradi*DEG_TO_RAD = Radianti
|
||||
#define PHIEXCLUSION_DEGREE 8.0 // Esclude dalla marchiature le coordinate polari con phi troppo vicine a 180.0 o a 0.0
|
||||
|
||||
#include "qstring.h"
|
||||
#include "math.h"
|
||||
#include <vector>
|
||||
|
||||
class utilsWatermark
|
||||
{
|
||||
public:
|
||||
utilsWatermark(void){}
|
||||
~utilsWatermark(void){}
|
||||
static unsigned int ComputeSeed(QString string_code);
|
||||
static std::vector< std::vector<double> > CreateWatermarkTable(unsigned int seed);
|
||||
static void sph2cartesian(double R, double theta, double phi, float &x, float &y, float &z);
|
||||
static void cartesian2sph(double x, double y, double z, double &R, double &theta, double &phi);
|
||||
static double round(double x);
|
||||
static double thresholdRo(double muRhoH0, double varRhoH0,
|
||||
double muRhoH1, double varRhoH1,
|
||||
double Pf, double &Pm);
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user