1 /*
2 */
3
4 /*
5
6 Copyright (C) 2014 Ferrero Andrea
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21
22 */
23
24 /*
25
26 These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/
27
28 */
29
30 // #include <vips/cimg_funcs.h>
31
32 #include "../base/new_operation.hh"
33 #include "convert_colorspace.hh"
34 #include "icc_transform.hh"
35 #include "../operations/impulse_nr.hh"
36 #include "../operations/nlmeans.hh"
37 #include "denoise.hh"
38
39
DenoisePar()40 PF::DenoisePar::DenoisePar():
41 OpParBase(),
42 impulse_nr_enable("impulse_nr_enable",this,false),
43 impulse_nr_threshold("impulse_nr_threshold",this,50),
44 nlmeans_enable("nlmeans_enable",this,false),
45 nlmeans_radius("nlmeans_radius",this,2),
46 nlmeans_strength("nlmeans_strength",this,50),
47 nlmeans_luma_frac("nlmeans_luma_frac",this,0.5),
48 nlmeans_chroma_frac("nlmeans_chroma_frac",this,1),
49 iterations("iterations",this,1),
50 amplitude("amplitude",this,100),
51 sharpness("sharpness",this,0.9),
52 anisotropy("anisotropy",this,0.15),
53 alpha("alpha",this,0.6),
54 sigma("sigma",this,1.1),
55 nr_mode("nr_mode",this,PF_NR_ANIBLUR,"ANIBLUR","Anisotropic Blur (G'Mic)")
56 {
57 convert2lab = PF::new_convert_colorspace();
58 PF::ConvertColorspacePar* csconvpar = dynamic_cast<PF::ConvertColorspacePar*>(convert2lab->get_par());
59 if(csconvpar) {
60 csconvpar->set_out_profile_mode( PF::PROF_MODE_DEFAULT );
61 csconvpar->set_out_profile_type( PF::PROF_TYPE_LAB );
62 }
63 convert2input = new_icc_transform();
64 impulse_nr = PF::new_impulse_nr();
65 nlmeans = PF::new_nlmeans();
66 set_type( "denoise" );
67
68 set_default_name( _("noise reduction") );
69 }
70
71
72
build(std::vector<VipsImage * > & in,int first,VipsImage * imap,VipsImage * omap,unsigned int & level)73 VipsImage* PF::DenoisePar::build(std::vector<VipsImage*>& in, int first,
74 VipsImage* imap, VipsImage* omap,
75 unsigned int& level)
76 {
77 VipsImage* srcimg = NULL;
78 if( in.size() > 0 ) srcimg = in[0];
79 VipsImage* mask;
80 VipsImage* out = srcimg;
81
82 if( !out ) return NULL;
83
84 PF_REF( out, "PF::DenoisePar::build(): out ref" );
85 if( (get_render_mode() == PF_RENDER_PREVIEW && level>0) ) {
86 return out;
87 }
88
89 if( !impulse_nr_enable.get() && !nlmeans_enable.get() ) {
90 return out;
91 }
92
93 ICCProfile* in_profile = PF::get_icc_profile( srcimg );
94
95 std::vector<VipsImage*> in2;
96
97 convert2lab->get_par()->set_image_hints( out );
98 convert2lab->get_par()->set_format( get_format() );
99 in2.clear(); in2.push_back( out );
100 VipsImage* labimg = convert2lab->get_par()->build( in2, 0, NULL, NULL, level );
101 if( !labimg ) {
102 std::cout<<"DenoisePar::build(): null Lab image"<<std::endl;
103 return out;
104 }
105 PF_UNREF( out, "DenoisePar::build(): out unref after Lab conversion" );
106 out = labimg;
107
108 if( impulse_nr_enable.get() && impulse_nr && impulse_nr->get_par() ) {
109 PF::ImpulseNRPar* imnrpar = dynamic_cast<PF::ImpulseNRPar*>(impulse_nr->get_par());
110 if( !imnrpar ) {
111 std::cout<<"DenoisePar::build(): failed to cast to ImpulseNRPar*"<<std::endl;
112 //PF_REF( out, "PF::DenoisePar::build(): out ref" );
113 return out;
114 }
115 imnrpar->set_threshold( impulse_nr_threshold.get() );
116 imnrpar->set_image_hints( out );
117 imnrpar->set_format( get_format() );
118 in2.clear(); in2.push_back( out );
119 VipsImage* imnrimg = imnrpar->build( in2, 0, NULL, NULL, level );
120 PF_UNREF( out, "DenoisePar::build(): out unref after imnrpar->build()" );
121 out = imnrimg;
122 }
123
124 //std::cout<<"DenoisePar::build(): nlmeans_enable.get()="<<nlmeans_enable.get()<<std::endl;
125 if( nlmeans_enable.get() && nlmeans && nlmeans->get_par() ) {
126 PF::NonLocalMeansPar* nrpar = dynamic_cast<PF::NonLocalMeansPar*>(nlmeans->get_par());
127 if( !nrpar ) {
128 std::cout<<"DenoisePar::build(): failed to cast to NonLocalMeansPar*"<<std::endl;
129 //PF_REF( out, "PF::DenoisePar::build(): out ref" );
130 return out;
131 }
132 nrpar->set_radius( nlmeans_radius.get() );
133 nrpar->set_strength( nlmeans_strength.get() );
134 nrpar->set_luma_frac( nlmeans_luma_frac.get() );
135 nrpar->set_chroma_frac( nlmeans_chroma_frac.get() );
136 nrpar->set_image_hints( out );
137 nrpar->set_format( get_format() );
138 in2.clear(); in2.push_back( out );
139 VipsImage* nrimg = nrpar->build( in2, 0, NULL, NULL, level );
140 PF_UNREF( out, "DenoisePar::build(): out unref after nrpar->build()" );
141 out = nrimg;
142 }
143
144
145 PF::ICCTransformPar* icc_par = dynamic_cast<PF::ICCTransformPar*>( convert2input->get_par() );
146 //std::cout<<"ImageArea::update(): icc_par="<<icc_par<<std::endl;
147 if( icc_par ) {
148 //std::cout<<"ImageArea::update(): setting display profile: "<<current_display_profile<<std::endl;
149 icc_par->set_out_profile( in_profile );
150 }
151 convert2input->get_par()->set_image_hints( out );
152 convert2input->get_par()->set_format( get_format() );
153 in2.clear(); in2.push_back( out );
154 //std::cout<<"DenoisePar::build(): calling convert2input->get_par()->build()"<<std::endl;
155 VipsImage* out2 = convert2input->get_par()->build(in2, 0, NULL, NULL, level );
156 PF_UNREF( out, "DenoisePar::update() out unref" );
157
158
159 /*
160 int fast_approx = 0;
161 if( (get_render_mode() == PF_RENDER_PREVIEW && level>0) )
162 fast_approx = 1;
163 out = vips_image_new();
164 if( im_greyc_mask( srcimg, out, NULL,
165 iterations.get(), amplitude.get(),
166 sharpness.get(), anisotropy.get(),
167 alpha.get(), sigma.get(), 0.8, 30, 2, 1, fast_approx ) )
168 return NULL;
169 */
170
171 return out2;
172 }
173