├── .gitignore ├── ImageWorkShop.sln ├── ImageWorkShop ├── Beeps.cpp ├── Beeps.h ├── ColorMap.cpp ├── ColorMap.h ├── ColorTransfer.cpp ├── ColorTransfer.h ├── FaceBeautification.cpp ├── FaceBeautification.h ├── GaussFilter.cpp ├── GaussFilter.h ├── GeneratedFiles │ ├── qrc_imageworkshop.cpp │ └── ui_imageworkshop.h ├── ImageSharpening.cpp ├── ImageSharpening.h ├── ImageWidget.cpp ├── ImageWidget.h ├── ImageWorkShop.vcxproj ├── ImageWorkShop.vcxproj.filters ├── Liquify.cpp ├── Liquify.h ├── Lomo.cpp ├── Lomo.h ├── MedianFilter.cpp ├── MedianFilter.h ├── MyPatchMatch.cpp ├── MyPatchMatch.h ├── PatchMatch.cpp ├── PatchMatch.h ├── Saturation.cpp ├── Saturation.h ├── Vignette.cpp ├── Vignette.h ├── WhiteBalance.cpp ├── WhiteBalance.h ├── imageworkshop.cpp ├── imageworkshop.h ├── imageworkshop.qrc ├── imageworkshop.ui ├── main.cpp └── openclShader │ ├── jumpFlooding.cl │ ├── jumpFloodingCopy.cl │ └── jumpFloodingRestrict.cl ├── README.md ├── filter_intro.pdf └── patchmatch_intro.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | *.sdf 2 | *.opensdf 3 | Win32/ 4 | ImageWorkShop/Debug 5 | ImageWorkShop/Release 6 | ImageWorkShop/GeneratedFiles/Debug 7 | ImageWorkShop/GeneratedFiles/Release -------------------------------------------------------------------------------- /ImageWorkShop.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageWorkShop", "ImageWorkShop\ImageWorkShop.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Win32.Build.0 = Debug|Win32 16 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64 17 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64 18 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|Win32.ActiveCfg = Release|Win32 19 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|Win32.Build.0 = Release|Win32 20 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64 21 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | GlobalSection(ExtensibilityGlobals) = postSolution 27 | Qt5Version = msvc2012-5.1.1-win32 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /ImageWorkShop/Beeps.cpp: -------------------------------------------------------------------------------- 1 | #include "Beeps.h" 2 | #include 3 | Beeps::Beeps(){} 4 | void Beeps::beeps(cv::Mat &image, int iter, double photometricStandardDeviationval, double spatialDecayval){ 5 | int row = image.rows; 6 | int col = image.cols; 7 | photometricStandardDeviation = photometricStandardDeviationval; 8 | spatialDecay = spatialDecayval; 9 | for(int i = 0; i < iter; i++){ 10 | cv::Mat duplicateImg(image.size(), CV_64F); 11 | image.copyTo(duplicateImg); 12 | beepsHorizontalVertical(duplicateImg); 13 | beepsVerticalHorizontal(image); 14 | 15 | for(int row = 0; row < image.rows; row++){ 16 | for(int col = 0; col < image.cols; col++){ 17 | image.at(row, col) = (image.at(row, col) + duplicateImg.at(row, col)) / 2; 18 | } 19 | } 20 | } 21 | } 22 | 23 | void Beeps::beepsVerticalHorizontal(cv::Mat &image){ 24 | cv::Mat p(image.size(), CV_64F); 25 | cv::Mat r(image.size(), CV_64F); 26 | cv::Mat g(image.size(), CV_64F); 27 | //img = image.t(); 28 | g = image.t(); 29 | 30 | g.copyTo(p); 31 | g.copyTo(r); 32 | 33 | progressive(p); 34 | gain(g); 35 | regressive(r); 36 | 37 | for(int row = 0; row < g.rows; row++){ 38 | for(int col = 0; col < g.cols; col++){ 39 | r.at(row, col) += p.at(row, col) - g.at(row, col); 40 | } 41 | } 42 | 43 | g = r.t(); 44 | g.copyTo(p); 45 | g.copyTo(r); 46 | 47 | progressive(p); 48 | gain(g); 49 | regressive(r); 50 | 51 | for(int row = 0; row < g.rows; row++){ 52 | for(int col = 0; col < g.cols; col++){ 53 | image.at(row, col) = p.at(row, col) - g.at(row, col) + r.at(row, col); 54 | } 55 | } 56 | 57 | } 58 | 59 | void Beeps::beepsHorizontalVertical(cv::Mat &image){ 60 | cv::Mat p(image.size(), CV_64F); 61 | cv::Mat r(image.size(), CV_64F); 62 | cv::Mat g(image.size(), CV_64F); 63 | 64 | image.copyTo(g); 65 | g.copyTo(p); 66 | g.copyTo(r); 67 | 68 | progressive(p); 69 | gain(g); 70 | regressive(r); 71 | 72 | for(int row = 0; row < g.rows; row++){ 73 | for(int col = 0; col < g.cols; col++){ 74 | r.at(row, col) += p.at(row, col) - g.at(row, col); 75 | } 76 | } 77 | 78 | g = r.t(); 79 | g.copyTo(p); 80 | g.copyTo(r); 81 | 82 | progressive(p); 83 | gain(g); 84 | regressive(r); 85 | 86 | for(int row = 0; row < g.rows; row++){ 87 | for(int col = 0; col < g.cols; col++){ 88 | r.at(row, col) += p.at(row, col) - g.at(row, col); 89 | } 90 | } 91 | image = r.t(); 92 | } 93 | 94 | void Beeps::progressive(cv::Mat &image){ 95 | double mur, mug, mub; 96 | double c = -0.5 / (photometricStandardDeviation * photometricStandardDeviation); 97 | double spatialContraDecay = 1 - spatialDecay; 98 | double rho = spatialContraDecay + 1; 99 | 100 | double result; 101 | for(int row = 0; row < image.rows; row++){ 102 | for(int col = 0; col < image.cols; col++){ 103 | if(col == 0){ 104 | image.at(row, col).val[0] = (char)(image.at(row, col).val[0] / rho); 105 | image.at(row, col).val[1] = (char)(image.at(row, col).val[1] / rho); 106 | image.at(row, col).val[2] = (char)(image.at(row, col).val[2] / rho); 107 | } 108 | else{ 109 | mub = image.at(row, col).val[0] - rho * image.at(row, col - 1).val[0]; 110 | mub = spatialContraDecay * exp(c * mub * mub); 111 | result = image.at(row, col - 1).val[0] * mub + image.at(row, col).val[0] * (1 - mub) / rho; 112 | image.at(row, col).val[0] = (char)result; 113 | 114 | mug = image.at(row, col).val[1] - rho * image.at(row, col - 1).val[1]; 115 | mug = spatialContraDecay * exp(c * mug * mug); 116 | result = image.at(row, col - 1).val[1] * mug + image.at(row, col).val[1] * (1 - mug) / rho; 117 | image.at(row, col).val[1] = (char)result; 118 | 119 | mur = image.at(row, col).val[2] - rho * image.at(row, col - 1).val[2]; 120 | mur = spatialContraDecay * exp(c * mur * mur); 121 | result = image.at(row, col - 1).val[2] * mur + image.at(row, col).val[2] * (1 - mur) / rho; 122 | image.at(row, col).val[2] = (char)result; 123 | } 124 | } 125 | } 126 | } 127 | 128 | void Beeps::regressive(cv::Mat &image){ 129 | double mur, mug, mub; 130 | double c = -0.5 / (photometricStandardDeviation * photometricStandardDeviation); 131 | double spatialContraDecay = 1 - spatialDecay; 132 | double rho = spatialContraDecay + 1; 133 | 134 | double result; 135 | for(int row = 0; row < image.rows; row++){ 136 | for(int col = image.cols - 1; col >= 0; col--){ 137 | if(col == image.cols - 1){ 138 | image.at(row, col).val[0] = (char)(image.at(row, col).val[0] / rho); 139 | image.at(row, col).val[1] = (char)(image.at(row, col).val[1] / rho); 140 | image.at(row, col).val[2] = (char)(image.at(row, col).val[2] / rho); 141 | } 142 | else{ 143 | mub = image.at(row, col).val[0] - rho * image.at(row, col + 1).val[0]; 144 | mub = spatialContraDecay * exp(c * mub * mub); 145 | result = image.at(row, col + 1).val[0] * mub + image.at(row, col).val[0] * (1 - mub) / rho; 146 | image.at(row, col).val[0] = (char)result; 147 | 148 | mug = image.at(row, col).val[1] - rho * image.at(row, col + 1).val[1]; 149 | mug = spatialContraDecay * exp(c * mug * mug); 150 | result = image.at(row, col + 1).val[1] * mug + image.at(row, col).val[1] * (1 - mug) / rho; 151 | image.at(row, col).val[1] = (char)result; 152 | 153 | mur = image.at(row, col).val[2] - rho * image.at(row, col + 1).val[2]; 154 | mur = spatialContraDecay * exp(c * mur * mur); 155 | result = image.at(row, col + 1).val[2] * mur + image.at(row, col).val[2] * (1 - mur) / rho; 156 | image.at(row, col).val[2] = (char)result; 157 | } 158 | } 159 | } 160 | } 161 | 162 | void Beeps::gain(cv::Mat &image){ 163 | double spatialContraDecay = 1 - spatialDecay; 164 | double mu = (1 - spatialContraDecay) * (1 + spatialContraDecay); 165 | 166 | for(int row = 0; row < image.rows; row++){ 167 | for(int col = 0; col < image.cols; col++){ 168 | image.at(row, col).val[0] = (char)(image.at(row, col).val[0] * mu); 169 | image.at(row, col).val[1] = (char)(image.at(row, col).val[1] * mu); 170 | image.at(row, col).val[2] = (char)(image.at(row, col).val[2] * mu); 171 | } 172 | } 173 | } 174 | 175 | void Beeps::beepsVerticalHorizontal(double *data, int width, int height){ 176 | double *g = new double[width * height]; 177 | 178 | int m = 0; 179 | for (int k2 = 0; (k2 < height); k2++) { 180 | int n = k2; 181 | for (int k1 = 0; (k1 < width); k1++) { 182 | g[n] = (double)data[m++]; 183 | n += height; 184 | } 185 | } 186 | //dataCopy(data, g, width * height); 187 | 188 | double *p = new double[width * height]; 189 | double *r = new double[width * height]; 190 | 191 | dataCopy(g, p, width * height); 192 | dataCopy(g, r, width * height); 193 | 194 | for (int k1 = 0; (k1 < width); k1++) { 195 | progressive(p, k1 * height, height); 196 | gain(g, k1 * height, height); 197 | regressive(r, k1 * height, height); 198 | } 199 | 200 | for (int k = 0, K = width * height; (k < K); k++) { 201 | r[k] += p[k] - g[k]; 202 | } 203 | 204 | m = 0; 205 | for (int k1 = 0; (k1 < width); k1++) { 206 | int n = k1; 207 | for (int k2 = 0; (k2 < height); k2++) { 208 | g[n] = r[m++]; 209 | n += width; 210 | } 211 | } 212 | 213 | dataCopy(g, p, width * height); 214 | dataCopy(g, r, width * height); 215 | 216 | for (int k2 = 0; (k2 < height); k2++) { 217 | progressive(p, k2 * width, width); 218 | gain(g, k2 * width, width); 219 | regressive(r, k2 * width, width); 220 | } 221 | 222 | for (int k = 0, K = width * height; (k < K); k++) { 223 | data[k] = (float)(p[k] - g[k] + r[k]); 224 | } 225 | } 226 | void Beeps::beepsHorizontalVertical(double *data, int width, int height){ 227 | double *g = new double[width * height]; 228 | dataCopy(data, g, width * height); 229 | 230 | double *p = new double[width * height]; 231 | double *r = new double[width * height]; 232 | 233 | dataCopy(g, p, width * height); 234 | dataCopy(g, r, width * height); 235 | 236 | for (int k2 = 0; (k2 < height); k2++) { 237 | progressive(p, k2 * width, width); 238 | gain(g, k2 * width, width); 239 | regressive(r, k2 * width, width); 240 | } 241 | for (int k = 0, K = width * height; (k < K); k++) { 242 | r[k] += p[k] - g[k]; 243 | } 244 | 245 | int m = 0; 246 | for (int k2 = 0; (k2 < height); k2++) { 247 | int n = k2; 248 | for (int k1 = 0; (k1 < width); k1++) { 249 | g[n] = r[m++]; 250 | n += height; 251 | } 252 | } 253 | 254 | dataCopy(g, p, width * height); 255 | dataCopy(g, r, width * height); 256 | 257 | for (int k1 = 0; (k1 < width); k1++) { 258 | progressive(p, k1 * height, height); 259 | gain(g, k1 * height, height); 260 | regressive(r, k1 * height, height); 261 | } 262 | for (int k = 0, K = width * height; (k < K); k++) { 263 | r[k] += p[k] - g[k]; 264 | } 265 | 266 | m = 0; 267 | for (int k1 = 0; (k1 < width); k1++) { 268 | int n = k1; 269 | for (int k2 = 0; (k2 < height); k2++) { 270 | data[n] = (float)r[m++]; 271 | n += width; 272 | } 273 | } 274 | } 275 | void Beeps::progressive(double *data, int startIndex, int length){ 276 | double c = -0.5 / (photometricStandardDeviation * photometricStandardDeviation); 277 | double spatialContraDecay = 1 - spatialDecay; 278 | double rho = spatialContraDecay + 1; 279 | 280 | double mu = 0.0; 281 | data[startIndex] /= rho; 282 | 283 | for (int k = startIndex + 1, K = startIndex + length;(k < K); k++) { 284 | mu = data[k] - rho * data[k - 1]; 285 | mu = spatialContraDecay * exp(c * mu * mu); 286 | data[k] = data[k - 1] * mu + data[k] * (1.0 - mu) / rho; 287 | } 288 | } 289 | void Beeps::regressive(double *data, int startIndex, int length){ 290 | double c = -0.5 / (photometricStandardDeviation * photometricStandardDeviation); 291 | double spatialContraDecay = 1 - spatialDecay; 292 | double rho = spatialContraDecay + 1; 293 | 294 | double mu = 0.0; 295 | data[startIndex + length - 1] /= rho; 296 | 297 | for (int k = startIndex + length - 2; (startIndex <= k); k--) { 298 | mu = data[k] - rho * data[k + 1]; 299 | mu = spatialContraDecay * exp(c * mu * mu); 300 | data[k] = data[k + 1] * mu + data[k] * (1.0 - mu) / rho; 301 | } 302 | } 303 | void Beeps::gain(double *data, int startIndex, int length){ 304 | double spatialContraDecay = 1 - spatialDecay; 305 | double mu = (1 - spatialContraDecay) * (1 + spatialContraDecay); 306 | 307 | for (int k = startIndex, K = startIndex + length; (k < K); k++) { 308 | data[k] *= mu; 309 | } 310 | } 311 | 312 | void Beeps::dataCopy(double *data, double *target, int length){ 313 | for(int i = 0; i < length; i++) 314 | target[i] = data[i]; 315 | } 316 | 317 | void Beeps::beeps2(cv::Mat &image, int iter, double photometricStandardDeviationval, double spatialDecayval){ 318 | int rows = image.rows; 319 | int cols = image.cols; 320 | photometricStandardDeviation = photometricStandardDeviationval; 321 | spatialDecay = spatialDecayval; 322 | 323 | 324 | double *dataR = new double[rows * cols]; 325 | double *dataG = new double[rows * cols]; 326 | double *dataB = new double[rows * cols]; 327 | double *dataDuplicateR = new double[rows * cols]; 328 | double *dataDuplicateG = new double[rows * cols]; 329 | double *dataDuplicateB = new double[rows * cols]; 330 | //#define length 550 * 500 331 | // double dataR[length]; 332 | // double dataG[length]; 333 | // double dataB[length]; 334 | // double dataDuplicateR[length]; 335 | // double dataDuplicateG[length]; 336 | // double dataDuplicateB[length]; 337 | int k = 0; 338 | for(int row = 0; row < rows; row++){ 339 | for(int col = 0; col < cols; col++){ 340 | dataB[k] = image.at(row, col).val[0]; 341 | dataG[k] = image.at(row, col).val[1]; 342 | dataR[k] = image.at(row, col).val[2]; 343 | k++; 344 | } 345 | } 346 | 347 | for(int i = 0; i < iter; i++){ 348 | dataCopy(dataB, dataDuplicateB, rows * cols); 349 | dataCopy(dataG, dataDuplicateG, rows * cols); 350 | dataCopy(dataR, dataDuplicateR, rows * cols); 351 | 352 | beepsHorizontalVertical(dataDuplicateB, cols, rows); 353 | beepsVerticalHorizontal(dataB, cols, rows); 354 | 355 | beepsHorizontalVertical(dataDuplicateG, cols, rows); 356 | beepsVerticalHorizontal(dataG, cols, rows); 357 | 358 | beepsHorizontalVertical(dataDuplicateR, cols, rows); 359 | beepsVerticalHorizontal(dataR, cols, rows); 360 | 361 | for(int i = 0; i < cols * rows; i++){ 362 | dataB[i] = (dataB[i] + dataDuplicateB[i]) * 0.5; 363 | dataG[i] = (dataG[i] + dataDuplicateG[i]) * 0.5; 364 | dataR[i] = (dataR[i] + dataDuplicateR[i]) * 0.5; 365 | } 366 | } 367 | 368 | k = 0; 369 | int lower = 0, upper = 255; 370 | for(int row = 0; row < rows; row++){ 371 | for(int col = 0; col < cols; col++){ 372 | if(dataB[k] > upper) 373 | dataB[k] = upper; 374 | else if(dataB[k] < lower) 375 | dataB[k] = lower; 376 | 377 | if(dataG[k] > upper) 378 | dataG[k] = upper; 379 | else if(dataG[k] < lower) 380 | dataG[k] = lower; 381 | 382 | if(dataR[k] > upper) 383 | dataR[k] = upper; 384 | else if(dataR[k] < lower) 385 | dataR[k] = lower; 386 | image.at(row, col).val[0] = (char)(dataB[k]); 387 | image.at(row, col).val[1] = (char)(dataG[k]); 388 | image.at(row, col).val[2] = (char)(dataR[k]); 389 | k++; 390 | } 391 | } 392 | } -------------------------------------------------------------------------------- /ImageWorkShop/Beeps.h: -------------------------------------------------------------------------------- 1 | #ifndef BEEPS_H 2 | #define BEEPS_H 3 | #include 4 | #include 5 | #include 6 | struct BeepsHorizontalVertical{ 7 | 8 | }; 9 | 10 | struct BeepsVerticalHorizontal{ 11 | 12 | }; 13 | 14 | struct BeepsProgressive{ 15 | 16 | }; 17 | 18 | struct BeepsRegressive{ 19 | 20 | }; 21 | 22 | struct Beeps{ 23 | public: 24 | cv::Mat image; 25 | double rhp; 26 | double spatialDecay; 27 | double c; 28 | double photometricStandardDeviation; 29 | Beeps(); 30 | void beeps(cv::Mat &image, int iter, double photometricStandardDeviationval, double spatialDecayval); 31 | void beepsVerticalHorizontal(cv::Mat &image); 32 | void beepsHorizontalVertical(cv::Mat &image); 33 | void progressive(cv::Mat &image); 34 | void regressive(cv::Mat &image); 35 | void gain(cv::Mat &image); 36 | 37 | void beeps2(cv::Mat &image, int iter, double photometricStandardDeviationval, double spatialDecayval); 38 | void beepsVerticalHorizontal(double *data, int width, int height); 39 | void beepsHorizontalVertical(double *data, int width, int height); 40 | void progressive(double *data, int begin, int length); 41 | void regressive(double *data, int begin, int length); 42 | void gain(double *data, int begin, int length); 43 | void dataCopy(double *data, double *target, int length); 44 | //int Partition(int *sort, int begin, int end); 45 | ///void QuickSort(int *sort, int begin, int end); 46 | }; 47 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/ColorMap.cpp: -------------------------------------------------------------------------------- 1 | #include "ColorMap.h" 2 | 3 | ColorMap::ColorMap(){ 4 | 5 | } 6 | 7 | void ColorMap::computeFractal(cv::Mat gray, int radius){ 8 | 9 | } -------------------------------------------------------------------------------- /ImageWorkShop/ColorMap.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_MAP_H 2 | #define COLOR_MAP_H 3 | #include 4 | #include 5 | #include 6 | struct ColorMap{ 7 | public: 8 | cv::Mat faceMask; 9 | ColorMap(); 10 | int width; 11 | int height; 12 | 13 | void computeFractal(cv::Mat gray, int radius); 14 | }; 15 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/ColorTransfer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunsiy10/ImageWorkShop/14013beccab1f7b6894cac92e2f312c2ef622589/ImageWorkShop/ColorTransfer.cpp -------------------------------------------------------------------------------- /ImageWorkShop/ColorTransfer.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_TRANSFER_H 2 | #define COLOR_TRANSFER_H 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | using namespace cv; 8 | class Point2D{ 9 | public: 10 | int x; 11 | int y; 12 | Point2D(int x_, int y_){ 13 | x = x_; 14 | y = y_; 15 | } 16 | }; 17 | class ColorTransfer 18 | { 19 | private: 20 | Mat srcImg; 21 | Mat targetImg; 22 | Mat srcImg_lab;//CV_32FC3 23 | Mat targetImg_lab;//CV_32FC3 24 | float *srcD; 25 | float *targetD; 26 | float *srcL; 27 | float *targetL; 28 | //Mat result_lab; 29 | vector srcMeans; 30 | vector srcVariances; 31 | vector targetMeans; 32 | vector targetVariances; 33 | void initialize(); 34 | void computeMeans(); 35 | void computeVariances(); 36 | void computeLocalVariances(Mat &gray, int radius, Mat &result); 37 | void computeFractal(Mat &gray, int radius, float* &D, float* &L); 38 | 39 | void fractalTransfer(Mat &srcImg_32F, Mat &targetImg_32F, Mat &c1, Mat &c2); 40 | public: 41 | Mat result; 42 | void solve(); 43 | void localVarianceTransfer(Mat &src, Mat &tgt); 44 | 45 | ColorTransfer(){} 46 | 47 | ColorTransfer(Mat src, Mat target):srcImg(src), targetImg(target) 48 | { 49 | srcMeans.resize(3, 0.f); 50 | srcVariances.resize(3, 0.f); 51 | targetMeans.resize(3, 0.f); 52 | targetVariances.resize(3, 0.f); 53 | srcD = NULL; 54 | srcL = NULL; 55 | targetL = NULL; 56 | targetD = NULL; 57 | solve(); 58 | } 59 | }; 60 | 61 | 62 | 63 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/FaceBeautification.cpp: -------------------------------------------------------------------------------- 1 | #include "FaceBeautification.h" 2 | #include 3 | #include 4 | #include 5 | FaceBeautification::FaceBeautification(){ 6 | 7 | } 8 | void FaceBeautification::genFaceMask(cv::Mat &image){ 9 | image.copyTo(faceMask); 10 | int r, g, b, sum, t1, t2, lower, upper; 11 | for(int row = 0; row < image.size().height; row++){ 12 | for(int col = 0; col < image.size().width; col++){ 13 | b = image.at(row, col).val[0]; 14 | g = image.at(row, col).val[1]; 15 | r = image.at(row, col).val[2]; 16 | 17 | faceMask.at(row, col).val[0] = 0; 18 | faceMask.at(row, col).val[1] = 0; 19 | faceMask.at(row, col).val[2] = 0; 20 | if(r - g >= 45){ 21 | if(g > b){ 22 | sum = b + r + g; 23 | t1 = 156 * r - 52 * sum; 24 | t2 = 156 * g - 52 * sum; 25 | if(t1 * t1 + t2 * t2 >= sum * sum * 39 / 4){ 26 | t1 = 10000 * g * sum; 27 | lower = -7760 * r * r + 5601 * r * sum + 1766 * sum * sum; 28 | if(t1 > lower){ 29 | upper = -13767 * r * r + 10743 * r * sum + 1452 * sum * sum; 30 | if(t1 < upper){ 31 | faceMask.at(row, col).val[0] = 255; 32 | faceMask.at(row, col).val[1] = 255; 33 | faceMask.at(row, col).val[2] = 255; 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | 41 | } 42 | } 43 | //cv::imshow("mask", faceMask) ; 44 | 45 | } 46 | 47 | void FaceBeautification::bilateralFilter(cv::Mat &image, double Deviationval, double spatialDecayval){ 48 | myBeeps.beeps2(image, 1, Deviationval, spatialDecayval); 49 | //myBeeps.beeps(image, 1, 10, 0.02); 50 | } 51 | 52 | void FaceBeautification::curve(cv::Mat &image, int beta){ 53 | int r, g, b; 54 | double s; 55 | int table[256]; 56 | for(int i = 0; i < 256; i++){ 57 | s = log(i * 1.0 / 255 * (beta - 1) + 1) / (log(beta)); 58 | s *= 255; 59 | if(s < 0) 60 | s = 0; 61 | else if(s > 255) 62 | s = 255; 63 | table[i] = (int)s; 64 | } 65 | for(int row = 0; row < image.rows; row++){ 66 | for(int col = 0; col < image.cols; col++){ 67 | b = image.at(row, col).val[0]; 68 | g = image.at(row, col).val[1]; 69 | r = image.at(row, col).val[2]; 70 | 71 | b = table[b]; 72 | g = table[g]; 73 | r = table[r]; 74 | 75 | image.at(row, col).val[0] = b; 76 | image.at(row, col).val[1] = g; 77 | image.at(row, col).val[2] = r; 78 | } 79 | } 80 | } 81 | 82 | //void FaceBeautification::genFaceMask2(cv::Mat &image){ 83 | // IplImage* img = NULL; 84 | // IplImage* cutImg = NULL; 85 | // CvMemStorage* storage = cvCreateMemStorage(0); 86 | // //CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("data.xml", 0, 0, 0); 87 | // CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt2.xml", 0, 0, 0); 88 | // CvSeq* faces; 89 | // char save_path[100]; 90 | // char path[100]; 91 | // int j; 92 | // int index = -1; 93 | // for (int i = 5 ; i <= 100; i++) 94 | // { 95 | // 96 | // sprintf(path,"..\\20140622jiezhen\\%d.bmp", i); 97 | // sprintf(save_path,"..\\GABCUT\\%d.bmp", i); 98 | // img = cvLoadImage(path, 0); 99 | // 100 | // 101 | // faces = cvHaarDetectObjects(img, cascade, storage, 1.2, 2, 0, cvSize(25,25) ); 102 | // if (faces->total == 0) 103 | // continue; 104 | // cvSetImageROI(img, *((CvRect*)cvGetSeqElem( faces, 0))); 105 | // cvSaveImage(save_path, img); 106 | // cvResetImageROI(img); 107 | // 108 | // } 109 | //} -------------------------------------------------------------------------------- /ImageWorkShop/FaceBeautification.h: -------------------------------------------------------------------------------- 1 | #ifndef FACE_BEAUTIFICATION_H 2 | #define FACE_BEAUTIFICATION_H 3 | #include 4 | #include 5 | #include 6 | #include "Beeps.h" 7 | struct FaceBeautification{ 8 | public: 9 | cv::Mat faceMask; 10 | 11 | Beeps myBeeps; 12 | FaceBeautification(); 13 | void genFaceMask(cv::Mat &image); 14 | //void genFaceMask2(cv::Mat &image); 15 | void genKernel(double *kernel, int radius); 16 | void bilateralFilter(cv::Mat &imagev, double Deviationval, double spatialDecayval); 17 | void curve(cv::Mat &image, int beta); 18 | //int Partition(int *sort, int begin, int end); 19 | ///void QuickSort(int *sort, int begin, int end); 20 | }; 21 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/GaussFilter.cpp: -------------------------------------------------------------------------------- 1 | #include "GaussFilter.h" 2 | #include 3 | void GaussFilter::gaussFilter(cv::Mat &image, int radius){ 4 | cv::Mat img(image.size(), CV_64F); 5 | double *kernel = new double[radius * 2 + 1]; 6 | genKernel(kernel, radius); 7 | image.copyTo(img); 8 | 9 | for(int row = 0; row < image.size().height; row++){ 10 | for(int col = 0; col < image.size().width; col++){ 11 | double r = 0, g = 0, b = 0; 12 | for(int i = -radius; i <= radius; i++){ 13 | int c_col = col + i; 14 | if(c_col < 0) 15 | c_col *= -1; 16 | else if(c_col > image.size().width - 1) 17 | c_col = 2 * (image.size().width - 1) - c_col; 18 | 19 | b += image.at(row, c_col).val[0] * kernel[i + radius]; 20 | g += image.at(row, c_col).val[1] * kernel[i + radius]; 21 | r += image.at(row, c_col).val[2] * kernel[i + radius]; 22 | } 23 | img.at(row, col).val[0] = (int)b; 24 | img.at(row, col).val[1] = (int)g; 25 | img.at(row, col).val[2] = (int)r; 26 | } 27 | } 28 | image = img.t(); 29 | image.copyTo(img); 30 | 31 | for(int row = 0; row < image.size().height; row++){ 32 | for(int col = 0; col < image.size().width; col++){ 33 | double r = 0, g = 0, b = 0; 34 | for(int i = -radius; i <= radius; i++){ 35 | int c_col = col + i; 36 | if(c_col < 0) 37 | c_col *= -1; 38 | else if(c_col > image.size().width - 1) 39 | c_col = 2 * (image.size().width - 1) - c_col; 40 | 41 | b += image.at(row, c_col).val[0] * kernel[i + radius]; 42 | g += image.at(row, c_col).val[1] * kernel[i + radius]; 43 | r += image.at(row, c_col).val[2] * kernel[i + radius]; 44 | } 45 | img.at(row, col).val[0] = (int)b; 46 | img.at(row, col).val[1] = (int)g; 47 | img.at(row, col).val[2] = (int)r; 48 | } 49 | } 50 | image = img.t(); 51 | delete kernel; 52 | } 53 | 54 | void GaussFilter::genKernel(double *kernel, int radius){ 55 | double fx = 0; 56 | double PI = 3.1415926, e = 2.718281828; 57 | for(int i = 1; i <= radius; i++) 58 | fx += i * i * 1.0; 59 | fx = fx * 2 / (2 * radius + 1); 60 | for(int i = -radius; i < radius + 1; i++){ 61 | kernel[i + radius] = pow(e, -(radius * radius) / (2 * fx)) / sqrt(2 * PI * fx); 62 | } 63 | double sum = 0; 64 | for(int i = 0; i < radius * 2 + 1; i++){ 65 | sum += kernel[i]; 66 | } 67 | for(int i = 0; i < radius * 2 + 1; i++){ 68 | kernel[i] /= sum; 69 | } 70 | } -------------------------------------------------------------------------------- /ImageWorkShop/GaussFilter.h: -------------------------------------------------------------------------------- 1 | #ifndef GAUSSFILTER_H 2 | #define GAUSSFILTER_H 3 | #include 4 | #include 5 | #include 6 | struct GaussFilter{ 7 | public: 8 | void gaussFilter(cv::Mat &image, int radius); 9 | void genKernel(double *kernel, int radius); 10 | //int Partition(int *sort, int begin, int end); 11 | ///void QuickSort(int *sort, int begin, int end); 12 | }; 13 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/GeneratedFiles/qrc_imageworkshop.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** Resource object code 3 | ** 4 | ** Created by: The Resource Compiler for Qt version 5.4.1 5 | ** 6 | ** WARNING! All changes made in this file will be lost! 7 | *****************************************************************************/ 8 | 9 | #ifdef QT_NAMESPACE 10 | # define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name 11 | # define QT_RCC_MANGLE_NAMESPACE0(x) x 12 | # define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b 13 | # define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b) 14 | # define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \ 15 | QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE)) 16 | #else 17 | # define QT_RCC_PREPEND_NAMESPACE(name) name 18 | # define QT_RCC_MANGLE_NAMESPACE(name) name 19 | #endif 20 | 21 | #ifdef QT_NAMESPACE 22 | namespace QT_NAMESPACE { 23 | #endif 24 | 25 | #ifdef QT_NAMESPACE 26 | } 27 | #endif 28 | 29 | int QT_RCC_MANGLE_NAMESPACE(qInitResources_imageworkshop)(); 30 | int QT_RCC_MANGLE_NAMESPACE(qInitResources_imageworkshop)() 31 | { 32 | return 1; 33 | } 34 | 35 | int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_imageworkshop)(); 36 | int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_imageworkshop)() 37 | { 38 | return 1; 39 | } 40 | 41 | namespace { 42 | struct initializer { 43 | initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_imageworkshop)(); } 44 | ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_imageworkshop)(); } 45 | } dummy; 46 | } 47 | -------------------------------------------------------------------------------- /ImageWorkShop/GeneratedFiles/ui_imageworkshop.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | ** Form generated from reading UI file 'imageworkshop.ui' 3 | ** 4 | ** Created by: Qt User Interface Compiler version 5.4.1 5 | ** 6 | ** WARNING! All changes made in this file will be lost when recompiling UI file! 7 | ********************************************************************************/ 8 | 9 | #ifndef UI_IMAGEWORKSHOP_H 10 | #define UI_IMAGEWORKSHOP_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | QT_BEGIN_NAMESPACE 36 | 37 | class Ui_ImageWorkShopClass 38 | { 39 | public: 40 | QAction *actionOpen; 41 | QAction *actionSave_as; 42 | QAction *actionStageSave; 43 | QAction *actionStageBack; 44 | QAction *actionCompare; 45 | QAction *actionImage_last_saved; 46 | QWidget *centralWidget; 47 | QGridLayout *gridLayout_2; 48 | QTabWidget *tabWidget; 49 | QWidget *tabFilter; 50 | QWidget *layoutWidget; 51 | QVBoxLayout *verticalLayout_5; 52 | QVBoxLayout *verticalLayout_4; 53 | QVBoxLayout *verticalLayout_2; 54 | QVBoxLayout *verticalLayout; 55 | QHBoxLayout *horizontalLayout_3; 56 | QPushButton *pushButtonMedian; 57 | QSpinBox *spinBoxMedian; 58 | QSpacerItem *horizontalSpacer; 59 | QHBoxLayout *horizontalLayout; 60 | QLabel *labelVignette; 61 | QSlider *horizontalSliderVignette; 62 | QLineEdit *lineEditVignette; 63 | QHBoxLayout *horizontalLayout_2; 64 | QLabel *labelGauss; 65 | QSlider *horizontalSliderGauss; 66 | QLineEdit *lineEditGauss; 67 | QHBoxLayout *horizontalLayout_5; 68 | QPushButton *pushButtonSharp; 69 | QSpacerItem *horizontalSpacer_3; 70 | QHBoxLayout *horizontalLayout_4; 71 | QLabel *labelBalance; 72 | QSlider *horizontalSliderBalance; 73 | QLineEdit *lineEditBalance; 74 | QHBoxLayout *horizontalLayout_6; 75 | QLabel *labelSaturation; 76 | QSlider *horizontalSliderSaturation; 77 | QLineEdit *lineEditSaturation; 78 | QHBoxLayout *horizontalLayout_7; 79 | QPushButton *pushButtonLiquify; 80 | QSpacerItem *horizontalSpacer_2; 81 | QPushButton *pushButtonLiquifyRadius; 82 | QSpinBox *spinBoxLiquifyRadius; 83 | QVBoxLayout *verticalLayout_3; 84 | QHBoxLayout *horizontalLayout_12; 85 | QHBoxLayout *horizontalLayout_8; 86 | QLabel *label_Lomo; 87 | QComboBox *comboBox_Lomo; 88 | QSpacerItem *horizontalSpacer_4; 89 | QHBoxLayout *horizontalLayout_9; 90 | QLabel *labelLomoR; 91 | QSlider *horizontalSliderLomoR; 92 | QLineEdit *lineEditLomoR; 93 | QHBoxLayout *horizontalLayout_10; 94 | QLabel *labelGauss_3; 95 | QSlider *horizontalSliderLomoG; 96 | QLineEdit *lineEditLomoG; 97 | QHBoxLayout *horizontalLayout_11; 98 | QLabel *labelGauss_4; 99 | QSlider *horizontalSliderLomoB; 100 | QLineEdit *lineEditLomoB; 101 | QWidget *layoutWidget1; 102 | QVBoxLayout *verticalLayout_7; 103 | QVBoxLayout *verticalLayout_6; 104 | QHBoxLayout *horizontalLayout_14; 105 | QLabel *label_5; 106 | QSlider *horizontalSliderWhitenSkinMask; 107 | QLineEdit *lineEditWhitenSkinMask; 108 | QHBoxLayout *horizontalLayout_15; 109 | QLabel *label_4; 110 | QSlider *horizontalSliderThreshold; 111 | QLineEdit *lineEditWhitenThreshold; 112 | QHBoxLayout *horizontalLayout_13; 113 | QPushButton *pushButton_Exfoliating; 114 | QSpacerItem *horizontalSpacer_7; 115 | QLabel *label_3; 116 | QSpinBox *spinBox_Vdev; 117 | QSpacerItem *horizontalSpacer_6; 118 | QLabel *label_2; 119 | QSpinBox *spinBox_Sdev; 120 | QSpacerItem *horizontalSpacer_5; 121 | QHBoxLayout *horizontalLayout_16; 122 | QLabel *label; 123 | QSlider *horizontalSliderWhitenSkin; 124 | QLineEdit *lineEditWhitenSkin; 125 | QSpacerItem *verticalSpacer; 126 | QWidget *tabFix; 127 | QLineEdit *lineEditBrushRadiusImageCopy; 128 | QPushButton *pushButtonMovePatch; 129 | QSlider *horizontalSliderBrushRadiusImageCopy; 130 | QLabel *label_6; 131 | QLabel *label_7; 132 | QLabel *label_8; 133 | QLabel *label_9; 134 | QSlider *horizontalSliderBrushRadiusImageInpaintHole; 135 | QLineEdit *lineEditBrushRadiusImageInpaintHole; 136 | QPushButton *pushButtonImageInpaintHoleResult; 137 | QLabel *label_10; 138 | QSlider *horizontalSliderBrushRadiusImageInpaintHoleRestrict; 139 | QLineEdit *lineEditBrushRadiusImageInpaintHoleRestrict; 140 | QPushButton *pushButtonImageInpaintHoleRestrictResult; 141 | QPushButton *pushButtonErodeRadius; 142 | QSpinBox *spinBoxErodeRadius; 143 | QPushButton *pushButtonImageInpaintHoleRestrictResultOut; 144 | QComboBox *comboBox_ifGpu; 145 | QLabel *label_11; 146 | QPushButton *pushButton_ClearRestrict; 147 | QPushButton *pushButton_ClearRegion; 148 | QWidget *tabColorMap; 149 | QPushButton *pushButton_Source; 150 | QPushButton *pushButton_Target; 151 | QPushButton *pushButton_Result; 152 | QPushButton *pushButton_ResultGrayToRGB; 153 | QMenuBar *menuBar; 154 | QMenu *menuFile; 155 | QMenu *menuStage; 156 | QToolBar *mainToolBar; 157 | QStatusBar *statusBar; 158 | 159 | void setupUi(QMainWindow *ImageWorkShopClass) 160 | { 161 | if (ImageWorkShopClass->objectName().isEmpty()) 162 | ImageWorkShopClass->setObjectName(QStringLiteral("ImageWorkShopClass")); 163 | ImageWorkShopClass->resize(502, 604); 164 | actionOpen = new QAction(ImageWorkShopClass); 165 | actionOpen->setObjectName(QStringLiteral("actionOpen")); 166 | actionSave_as = new QAction(ImageWorkShopClass); 167 | actionSave_as->setObjectName(QStringLiteral("actionSave_as")); 168 | actionStageSave = new QAction(ImageWorkShopClass); 169 | actionStageSave->setObjectName(QStringLiteral("actionStageSave")); 170 | actionStageBack = new QAction(ImageWorkShopClass); 171 | actionStageBack->setObjectName(QStringLiteral("actionStageBack")); 172 | actionCompare = new QAction(ImageWorkShopClass); 173 | actionCompare->setObjectName(QStringLiteral("actionCompare")); 174 | actionImage_last_saved = new QAction(ImageWorkShopClass); 175 | actionImage_last_saved->setObjectName(QStringLiteral("actionImage_last_saved")); 176 | centralWidget = new QWidget(ImageWorkShopClass); 177 | centralWidget->setObjectName(QStringLiteral("centralWidget")); 178 | gridLayout_2 = new QGridLayout(centralWidget); 179 | gridLayout_2->setSpacing(6); 180 | gridLayout_2->setContentsMargins(11, 11, 11, 11); 181 | gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); 182 | tabWidget = new QTabWidget(centralWidget); 183 | tabWidget->setObjectName(QStringLiteral("tabWidget")); 184 | tabFilter = new QWidget(); 185 | tabFilter->setObjectName(QStringLiteral("tabFilter")); 186 | layoutWidget = new QWidget(tabFilter); 187 | layoutWidget->setObjectName(QStringLiteral("layoutWidget")); 188 | layoutWidget->setGeometry(QRect(0, 0, 440, 323)); 189 | verticalLayout_5 = new QVBoxLayout(layoutWidget); 190 | verticalLayout_5->setSpacing(6); 191 | verticalLayout_5->setContentsMargins(11, 11, 11, 11); 192 | verticalLayout_5->setObjectName(QStringLiteral("verticalLayout_5")); 193 | verticalLayout_5->setContentsMargins(0, 0, 0, 0); 194 | verticalLayout_4 = new QVBoxLayout(); 195 | verticalLayout_4->setSpacing(6); 196 | verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4")); 197 | verticalLayout_2 = new QVBoxLayout(); 198 | verticalLayout_2->setSpacing(6); 199 | verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); 200 | verticalLayout = new QVBoxLayout(); 201 | verticalLayout->setSpacing(6); 202 | verticalLayout->setObjectName(QStringLiteral("verticalLayout")); 203 | horizontalLayout_3 = new QHBoxLayout(); 204 | horizontalLayout_3->setSpacing(6); 205 | horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3")); 206 | pushButtonMedian = new QPushButton(layoutWidget); 207 | pushButtonMedian->setObjectName(QStringLiteral("pushButtonMedian")); 208 | 209 | horizontalLayout_3->addWidget(pushButtonMedian); 210 | 211 | spinBoxMedian = new QSpinBox(layoutWidget); 212 | spinBoxMedian->setObjectName(QStringLiteral("spinBoxMedian")); 213 | spinBoxMedian->setMinimumSize(QSize(50, 0)); 214 | spinBoxMedian->setMinimum(1); 215 | spinBoxMedian->setMaximum(7); 216 | 217 | horizontalLayout_3->addWidget(spinBoxMedian); 218 | 219 | horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 220 | 221 | horizontalLayout_3->addItem(horizontalSpacer); 222 | 223 | 224 | verticalLayout->addLayout(horizontalLayout_3); 225 | 226 | horizontalLayout = new QHBoxLayout(); 227 | horizontalLayout->setSpacing(6); 228 | horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); 229 | labelVignette = new QLabel(layoutWidget); 230 | labelVignette->setObjectName(QStringLiteral("labelVignette")); 231 | QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); 232 | sizePolicy.setHorizontalStretch(0); 233 | sizePolicy.setVerticalStretch(0); 234 | sizePolicy.setHeightForWidth(labelVignette->sizePolicy().hasHeightForWidth()); 235 | labelVignette->setSizePolicy(sizePolicy); 236 | 237 | horizontalLayout->addWidget(labelVignette); 238 | 239 | horizontalSliderVignette = new QSlider(layoutWidget); 240 | horizontalSliderVignette->setObjectName(QStringLiteral("horizontalSliderVignette")); 241 | QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); 242 | sizePolicy1.setHorizontalStretch(0); 243 | sizePolicy1.setVerticalStretch(0); 244 | sizePolicy1.setHeightForWidth(horizontalSliderVignette->sizePolicy().hasHeightForWidth()); 245 | horizontalSliderVignette->setSizePolicy(sizePolicy1); 246 | horizontalSliderVignette->setMinimumSize(QSize(300, 0)); 247 | horizontalSliderVignette->setMaximum(28); 248 | horizontalSliderVignette->setSliderPosition(28); 249 | horizontalSliderVignette->setOrientation(Qt::Horizontal); 250 | 251 | horizontalLayout->addWidget(horizontalSliderVignette); 252 | 253 | lineEditVignette = new QLineEdit(layoutWidget); 254 | lineEditVignette->setObjectName(QStringLiteral("lineEditVignette")); 255 | sizePolicy1.setHeightForWidth(lineEditVignette->sizePolicy().hasHeightForWidth()); 256 | lineEditVignette->setSizePolicy(sizePolicy1); 257 | lineEditVignette->setMaximumSize(QSize(60, 16777215)); 258 | 259 | horizontalLayout->addWidget(lineEditVignette); 260 | 261 | 262 | verticalLayout->addLayout(horizontalLayout); 263 | 264 | horizontalLayout_2 = new QHBoxLayout(); 265 | horizontalLayout_2->setSpacing(6); 266 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 267 | labelGauss = new QLabel(layoutWidget); 268 | labelGauss->setObjectName(QStringLiteral("labelGauss")); 269 | sizePolicy.setHeightForWidth(labelGauss->sizePolicy().hasHeightForWidth()); 270 | labelGauss->setSizePolicy(sizePolicy); 271 | 272 | horizontalLayout_2->addWidget(labelGauss); 273 | 274 | horizontalSliderGauss = new QSlider(layoutWidget); 275 | horizontalSliderGauss->setObjectName(QStringLiteral("horizontalSliderGauss")); 276 | sizePolicy1.setHeightForWidth(horizontalSliderGauss->sizePolicy().hasHeightForWidth()); 277 | horizontalSliderGauss->setSizePolicy(sizePolicy1); 278 | horizontalSliderGauss->setMinimumSize(QSize(300, 0)); 279 | horizontalSliderGauss->setMinimum(1); 280 | horizontalSliderGauss->setMaximum(10); 281 | horizontalSliderGauss->setSliderPosition(1); 282 | horizontalSliderGauss->setOrientation(Qt::Horizontal); 283 | 284 | horizontalLayout_2->addWidget(horizontalSliderGauss); 285 | 286 | lineEditGauss = new QLineEdit(layoutWidget); 287 | lineEditGauss->setObjectName(QStringLiteral("lineEditGauss")); 288 | sizePolicy1.setHeightForWidth(lineEditGauss->sizePolicy().hasHeightForWidth()); 289 | lineEditGauss->setSizePolicy(sizePolicy1); 290 | lineEditGauss->setMaximumSize(QSize(60, 16777215)); 291 | 292 | horizontalLayout_2->addWidget(lineEditGauss); 293 | 294 | 295 | verticalLayout->addLayout(horizontalLayout_2); 296 | 297 | horizontalLayout_5 = new QHBoxLayout(); 298 | horizontalLayout_5->setSpacing(6); 299 | horizontalLayout_5->setObjectName(QStringLiteral("horizontalLayout_5")); 300 | pushButtonSharp = new QPushButton(layoutWidget); 301 | pushButtonSharp->setObjectName(QStringLiteral("pushButtonSharp")); 302 | 303 | horizontalLayout_5->addWidget(pushButtonSharp); 304 | 305 | horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 306 | 307 | horizontalLayout_5->addItem(horizontalSpacer_3); 308 | 309 | 310 | verticalLayout->addLayout(horizontalLayout_5); 311 | 312 | 313 | verticalLayout_2->addLayout(verticalLayout); 314 | 315 | horizontalLayout_4 = new QHBoxLayout(); 316 | horizontalLayout_4->setSpacing(6); 317 | horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4")); 318 | labelBalance = new QLabel(layoutWidget); 319 | labelBalance->setObjectName(QStringLiteral("labelBalance")); 320 | sizePolicy.setHeightForWidth(labelBalance->sizePolicy().hasHeightForWidth()); 321 | labelBalance->setSizePolicy(sizePolicy); 322 | 323 | horizontalLayout_4->addWidget(labelBalance); 324 | 325 | horizontalSliderBalance = new QSlider(layoutWidget); 326 | horizontalSliderBalance->setObjectName(QStringLiteral("horizontalSliderBalance")); 327 | sizePolicy1.setHeightForWidth(horizontalSliderBalance->sizePolicy().hasHeightForWidth()); 328 | horizontalSliderBalance->setSizePolicy(sizePolicy1); 329 | horizontalSliderBalance->setMinimumSize(QSize(300, 0)); 330 | horizontalSliderBalance->setMinimum(1); 331 | horizontalSliderBalance->setMaximum(30); 332 | horizontalSliderBalance->setPageStep(10); 333 | horizontalSliderBalance->setSliderPosition(1); 334 | horizontalSliderBalance->setOrientation(Qt::Horizontal); 335 | 336 | horizontalLayout_4->addWidget(horizontalSliderBalance); 337 | 338 | lineEditBalance = new QLineEdit(layoutWidget); 339 | lineEditBalance->setObjectName(QStringLiteral("lineEditBalance")); 340 | sizePolicy1.setHeightForWidth(lineEditBalance->sizePolicy().hasHeightForWidth()); 341 | lineEditBalance->setSizePolicy(sizePolicy1); 342 | lineEditBalance->setMaximumSize(QSize(60, 16777215)); 343 | 344 | horizontalLayout_4->addWidget(lineEditBalance); 345 | 346 | 347 | verticalLayout_2->addLayout(horizontalLayout_4); 348 | 349 | horizontalLayout_6 = new QHBoxLayout(); 350 | horizontalLayout_6->setSpacing(6); 351 | horizontalLayout_6->setObjectName(QStringLiteral("horizontalLayout_6")); 352 | labelSaturation = new QLabel(layoutWidget); 353 | labelSaturation->setObjectName(QStringLiteral("labelSaturation")); 354 | sizePolicy.setHeightForWidth(labelSaturation->sizePolicy().hasHeightForWidth()); 355 | labelSaturation->setSizePolicy(sizePolicy); 356 | 357 | horizontalLayout_6->addWidget(labelSaturation); 358 | 359 | horizontalSliderSaturation = new QSlider(layoutWidget); 360 | horizontalSliderSaturation->setObjectName(QStringLiteral("horizontalSliderSaturation")); 361 | sizePolicy1.setHeightForWidth(horizontalSliderSaturation->sizePolicy().hasHeightForWidth()); 362 | horizontalSliderSaturation->setSizePolicy(sizePolicy1); 363 | horizontalSliderSaturation->setMinimumSize(QSize(300, 0)); 364 | horizontalSliderSaturation->setMinimum(1); 365 | horizontalSliderSaturation->setMaximum(100); 366 | horizontalSliderSaturation->setPageStep(10); 367 | horizontalSliderSaturation->setSliderPosition(1); 368 | horizontalSliderSaturation->setOrientation(Qt::Horizontal); 369 | 370 | horizontalLayout_6->addWidget(horizontalSliderSaturation); 371 | 372 | lineEditSaturation = new QLineEdit(layoutWidget); 373 | lineEditSaturation->setObjectName(QStringLiteral("lineEditSaturation")); 374 | sizePolicy1.setHeightForWidth(lineEditSaturation->sizePolicy().hasHeightForWidth()); 375 | lineEditSaturation->setSizePolicy(sizePolicy1); 376 | lineEditSaturation->setMaximumSize(QSize(60, 16777215)); 377 | 378 | horizontalLayout_6->addWidget(lineEditSaturation); 379 | 380 | 381 | verticalLayout_2->addLayout(horizontalLayout_6); 382 | 383 | 384 | verticalLayout_4->addLayout(verticalLayout_2); 385 | 386 | horizontalLayout_7 = new QHBoxLayout(); 387 | horizontalLayout_7->setSpacing(6); 388 | horizontalLayout_7->setObjectName(QStringLiteral("horizontalLayout_7")); 389 | pushButtonLiquify = new QPushButton(layoutWidget); 390 | pushButtonLiquify->setObjectName(QStringLiteral("pushButtonLiquify")); 391 | 392 | horizontalLayout_7->addWidget(pushButtonLiquify); 393 | 394 | horizontalSpacer_2 = new QSpacerItem(198, 17, QSizePolicy::Maximum, QSizePolicy::Minimum); 395 | 396 | horizontalLayout_7->addItem(horizontalSpacer_2); 397 | 398 | pushButtonLiquifyRadius = new QPushButton(layoutWidget); 399 | pushButtonLiquifyRadius->setObjectName(QStringLiteral("pushButtonLiquifyRadius")); 400 | 401 | horizontalLayout_7->addWidget(pushButtonLiquifyRadius); 402 | 403 | spinBoxLiquifyRadius = new QSpinBox(layoutWidget); 404 | spinBoxLiquifyRadius->setObjectName(QStringLiteral("spinBoxLiquifyRadius")); 405 | spinBoxLiquifyRadius->setMinimum(10); 406 | spinBoxLiquifyRadius->setMaximum(100); 407 | spinBoxLiquifyRadius->setValue(20); 408 | 409 | horizontalLayout_7->addWidget(spinBoxLiquifyRadius); 410 | 411 | 412 | verticalLayout_4->addLayout(horizontalLayout_7); 413 | 414 | 415 | verticalLayout_5->addLayout(verticalLayout_4); 416 | 417 | verticalLayout_3 = new QVBoxLayout(); 418 | verticalLayout_3->setSpacing(6); 419 | verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3")); 420 | horizontalLayout_12 = new QHBoxLayout(); 421 | horizontalLayout_12->setSpacing(6); 422 | horizontalLayout_12->setObjectName(QStringLiteral("horizontalLayout_12")); 423 | horizontalLayout_8 = new QHBoxLayout(); 424 | horizontalLayout_8->setSpacing(6); 425 | horizontalLayout_8->setObjectName(QStringLiteral("horizontalLayout_8")); 426 | label_Lomo = new QLabel(layoutWidget); 427 | label_Lomo->setObjectName(QStringLiteral("label_Lomo")); 428 | 429 | horizontalLayout_8->addWidget(label_Lomo); 430 | 431 | comboBox_Lomo = new QComboBox(layoutWidget); 432 | comboBox_Lomo->setObjectName(QStringLiteral("comboBox_Lomo")); 433 | QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Fixed); 434 | sizePolicy2.setHorizontalStretch(0); 435 | sizePolicy2.setVerticalStretch(0); 436 | sizePolicy2.setHeightForWidth(comboBox_Lomo->sizePolicy().hasHeightForWidth()); 437 | comboBox_Lomo->setSizePolicy(sizePolicy2); 438 | comboBox_Lomo->setMinimumSize(QSize(100, 0)); 439 | comboBox_Lomo->setMaximumSize(QSize(100, 16777215)); 440 | 441 | horizontalLayout_8->addWidget(comboBox_Lomo); 442 | 443 | 444 | horizontalLayout_12->addLayout(horizontalLayout_8); 445 | 446 | horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 447 | 448 | horizontalLayout_12->addItem(horizontalSpacer_4); 449 | 450 | 451 | verticalLayout_3->addLayout(horizontalLayout_12); 452 | 453 | horizontalLayout_9 = new QHBoxLayout(); 454 | horizontalLayout_9->setSpacing(6); 455 | horizontalLayout_9->setObjectName(QStringLiteral("horizontalLayout_9")); 456 | labelLomoR = new QLabel(layoutWidget); 457 | labelLomoR->setObjectName(QStringLiteral("labelLomoR")); 458 | sizePolicy.setHeightForWidth(labelLomoR->sizePolicy().hasHeightForWidth()); 459 | labelLomoR->setSizePolicy(sizePolicy); 460 | 461 | horizontalLayout_9->addWidget(labelLomoR); 462 | 463 | horizontalSliderLomoR = new QSlider(layoutWidget); 464 | horizontalSliderLomoR->setObjectName(QStringLiteral("horizontalSliderLomoR")); 465 | sizePolicy1.setHeightForWidth(horizontalSliderLomoR->sizePolicy().hasHeightForWidth()); 466 | horizontalSliderLomoR->setSizePolicy(sizePolicy1); 467 | horizontalSliderLomoR->setMinimumSize(QSize(300, 0)); 468 | horizontalSliderLomoR->setMinimum(1); 469 | horizontalSliderLomoR->setMaximum(255); 470 | horizontalSliderLomoR->setValue(127); 471 | horizontalSliderLomoR->setSliderPosition(127); 472 | horizontalSliderLomoR->setOrientation(Qt::Horizontal); 473 | 474 | horizontalLayout_9->addWidget(horizontalSliderLomoR); 475 | 476 | lineEditLomoR = new QLineEdit(layoutWidget); 477 | lineEditLomoR->setObjectName(QStringLiteral("lineEditLomoR")); 478 | sizePolicy1.setHeightForWidth(lineEditLomoR->sizePolicy().hasHeightForWidth()); 479 | lineEditLomoR->setSizePolicy(sizePolicy1); 480 | lineEditLomoR->setMaximumSize(QSize(60, 16777215)); 481 | 482 | horizontalLayout_9->addWidget(lineEditLomoR); 483 | 484 | 485 | verticalLayout_3->addLayout(horizontalLayout_9); 486 | 487 | horizontalLayout_10 = new QHBoxLayout(); 488 | horizontalLayout_10->setSpacing(6); 489 | horizontalLayout_10->setObjectName(QStringLiteral("horizontalLayout_10")); 490 | labelGauss_3 = new QLabel(layoutWidget); 491 | labelGauss_3->setObjectName(QStringLiteral("labelGauss_3")); 492 | sizePolicy.setHeightForWidth(labelGauss_3->sizePolicy().hasHeightForWidth()); 493 | labelGauss_3->setSizePolicy(sizePolicy); 494 | 495 | horizontalLayout_10->addWidget(labelGauss_3); 496 | 497 | horizontalSliderLomoG = new QSlider(layoutWidget); 498 | horizontalSliderLomoG->setObjectName(QStringLiteral("horizontalSliderLomoG")); 499 | sizePolicy1.setHeightForWidth(horizontalSliderLomoG->sizePolicy().hasHeightForWidth()); 500 | horizontalSliderLomoG->setSizePolicy(sizePolicy1); 501 | horizontalSliderLomoG->setMinimumSize(QSize(300, 0)); 502 | horizontalSliderLomoG->setMinimum(1); 503 | horizontalSliderLomoG->setMaximum(255); 504 | horizontalSliderLomoG->setValue(127); 505 | horizontalSliderLomoG->setSliderPosition(127); 506 | horizontalSliderLomoG->setOrientation(Qt::Horizontal); 507 | 508 | horizontalLayout_10->addWidget(horizontalSliderLomoG); 509 | 510 | lineEditLomoG = new QLineEdit(layoutWidget); 511 | lineEditLomoG->setObjectName(QStringLiteral("lineEditLomoG")); 512 | sizePolicy1.setHeightForWidth(lineEditLomoG->sizePolicy().hasHeightForWidth()); 513 | lineEditLomoG->setSizePolicy(sizePolicy1); 514 | lineEditLomoG->setMaximumSize(QSize(60, 16777215)); 515 | 516 | horizontalLayout_10->addWidget(lineEditLomoG); 517 | 518 | 519 | verticalLayout_3->addLayout(horizontalLayout_10); 520 | 521 | horizontalLayout_11 = new QHBoxLayout(); 522 | horizontalLayout_11->setSpacing(6); 523 | horizontalLayout_11->setObjectName(QStringLiteral("horizontalLayout_11")); 524 | labelGauss_4 = new QLabel(layoutWidget); 525 | labelGauss_4->setObjectName(QStringLiteral("labelGauss_4")); 526 | sizePolicy.setHeightForWidth(labelGauss_4->sizePolicy().hasHeightForWidth()); 527 | labelGauss_4->setSizePolicy(sizePolicy); 528 | 529 | horizontalLayout_11->addWidget(labelGauss_4); 530 | 531 | horizontalSliderLomoB = new QSlider(layoutWidget); 532 | horizontalSliderLomoB->setObjectName(QStringLiteral("horizontalSliderLomoB")); 533 | sizePolicy1.setHeightForWidth(horizontalSliderLomoB->sizePolicy().hasHeightForWidth()); 534 | horizontalSliderLomoB->setSizePolicy(sizePolicy1); 535 | horizontalSliderLomoB->setMinimumSize(QSize(300, 0)); 536 | horizontalSliderLomoB->setMinimum(1); 537 | horizontalSliderLomoB->setMaximum(255); 538 | horizontalSliderLomoB->setValue(127); 539 | horizontalSliderLomoB->setSliderPosition(127); 540 | horizontalSliderLomoB->setOrientation(Qt::Horizontal); 541 | 542 | horizontalLayout_11->addWidget(horizontalSliderLomoB); 543 | 544 | lineEditLomoB = new QLineEdit(layoutWidget); 545 | lineEditLomoB->setObjectName(QStringLiteral("lineEditLomoB")); 546 | sizePolicy1.setHeightForWidth(lineEditLomoB->sizePolicy().hasHeightForWidth()); 547 | lineEditLomoB->setSizePolicy(sizePolicy1); 548 | lineEditLomoB->setMaximumSize(QSize(60, 16777215)); 549 | 550 | horizontalLayout_11->addWidget(lineEditLomoB); 551 | 552 | 553 | verticalLayout_3->addLayout(horizontalLayout_11); 554 | 555 | 556 | verticalLayout_5->addLayout(verticalLayout_3); 557 | 558 | layoutWidget1 = new QWidget(tabFilter); 559 | layoutWidget1->setObjectName(QStringLiteral("layoutWidget1")); 560 | layoutWidget1->setGeometry(QRect(0, 330, 456, 159)); 561 | verticalLayout_7 = new QVBoxLayout(layoutWidget1); 562 | verticalLayout_7->setSpacing(6); 563 | verticalLayout_7->setContentsMargins(11, 11, 11, 11); 564 | verticalLayout_7->setObjectName(QStringLiteral("verticalLayout_7")); 565 | verticalLayout_7->setContentsMargins(0, 0, 0, 0); 566 | verticalLayout_6 = new QVBoxLayout(); 567 | verticalLayout_6->setSpacing(6); 568 | verticalLayout_6->setObjectName(QStringLiteral("verticalLayout_6")); 569 | horizontalLayout_14 = new QHBoxLayout(); 570 | horizontalLayout_14->setSpacing(6); 571 | horizontalLayout_14->setObjectName(QStringLiteral("horizontalLayout_14")); 572 | label_5 = new QLabel(layoutWidget1); 573 | label_5->setObjectName(QStringLiteral("label_5")); 574 | 575 | horizontalLayout_14->addWidget(label_5); 576 | 577 | horizontalSliderWhitenSkinMask = new QSlider(layoutWidget1); 578 | horizontalSliderWhitenSkinMask->setObjectName(QStringLiteral("horizontalSliderWhitenSkinMask")); 579 | sizePolicy1.setHeightForWidth(horizontalSliderWhitenSkinMask->sizePolicy().hasHeightForWidth()); 580 | horizontalSliderWhitenSkinMask->setSizePolicy(sizePolicy1); 581 | horizontalSliderWhitenSkinMask->setMinimumSize(QSize(300, 0)); 582 | horizontalSliderWhitenSkinMask->setMinimum(2); 583 | horizontalSliderWhitenSkinMask->setMaximum(50); 584 | horizontalSliderWhitenSkinMask->setValue(5); 585 | horizontalSliderWhitenSkinMask->setSliderPosition(5); 586 | horizontalSliderWhitenSkinMask->setOrientation(Qt::Horizontal); 587 | 588 | horizontalLayout_14->addWidget(horizontalSliderWhitenSkinMask); 589 | 590 | lineEditWhitenSkinMask = new QLineEdit(layoutWidget1); 591 | lineEditWhitenSkinMask->setObjectName(QStringLiteral("lineEditWhitenSkinMask")); 592 | sizePolicy1.setHeightForWidth(lineEditWhitenSkinMask->sizePolicy().hasHeightForWidth()); 593 | lineEditWhitenSkinMask->setSizePolicy(sizePolicy1); 594 | lineEditWhitenSkinMask->setMaximumSize(QSize(60, 16777215)); 595 | 596 | horizontalLayout_14->addWidget(lineEditWhitenSkinMask); 597 | 598 | 599 | verticalLayout_6->addLayout(horizontalLayout_14); 600 | 601 | horizontalLayout_15 = new QHBoxLayout(); 602 | horizontalLayout_15->setSpacing(6); 603 | horizontalLayout_15->setObjectName(QStringLiteral("horizontalLayout_15")); 604 | label_4 = new QLabel(layoutWidget1); 605 | label_4->setObjectName(QStringLiteral("label_4")); 606 | 607 | horizontalLayout_15->addWidget(label_4); 608 | 609 | horizontalSliderThreshold = new QSlider(layoutWidget1); 610 | horizontalSliderThreshold->setObjectName(QStringLiteral("horizontalSliderThreshold")); 611 | sizePolicy1.setHeightForWidth(horizontalSliderThreshold->sizePolicy().hasHeightForWidth()); 612 | horizontalSliderThreshold->setSizePolicy(sizePolicy1); 613 | horizontalSliderThreshold->setMinimumSize(QSize(300, 0)); 614 | horizontalSliderThreshold->setMinimum(1); 615 | horizontalSliderThreshold->setMaximum(15); 616 | horizontalSliderThreshold->setValue(1); 617 | horizontalSliderThreshold->setSliderPosition(1); 618 | horizontalSliderThreshold->setOrientation(Qt::Horizontal); 619 | 620 | horizontalLayout_15->addWidget(horizontalSliderThreshold); 621 | 622 | lineEditWhitenThreshold = new QLineEdit(layoutWidget1); 623 | lineEditWhitenThreshold->setObjectName(QStringLiteral("lineEditWhitenThreshold")); 624 | sizePolicy1.setHeightForWidth(lineEditWhitenThreshold->sizePolicy().hasHeightForWidth()); 625 | lineEditWhitenThreshold->setSizePolicy(sizePolicy1); 626 | lineEditWhitenThreshold->setMaximumSize(QSize(60, 16777215)); 627 | 628 | horizontalLayout_15->addWidget(lineEditWhitenThreshold); 629 | 630 | 631 | verticalLayout_6->addLayout(horizontalLayout_15); 632 | 633 | horizontalLayout_13 = new QHBoxLayout(); 634 | horizontalLayout_13->setSpacing(6); 635 | horizontalLayout_13->setObjectName(QStringLiteral("horizontalLayout_13")); 636 | pushButton_Exfoliating = new QPushButton(layoutWidget1); 637 | pushButton_Exfoliating->setObjectName(QStringLiteral("pushButton_Exfoliating")); 638 | 639 | horizontalLayout_13->addWidget(pushButton_Exfoliating); 640 | 641 | horizontalSpacer_7 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 642 | 643 | horizontalLayout_13->addItem(horizontalSpacer_7); 644 | 645 | label_3 = new QLabel(layoutWidget1); 646 | label_3->setObjectName(QStringLiteral("label_3")); 647 | 648 | horizontalLayout_13->addWidget(label_3); 649 | 650 | spinBox_Vdev = new QSpinBox(layoutWidget1); 651 | spinBox_Vdev->setObjectName(QStringLiteral("spinBox_Vdev")); 652 | spinBox_Vdev->setMinimum(8); 653 | spinBox_Vdev->setMaximum(12); 654 | spinBox_Vdev->setValue(10); 655 | 656 | horizontalLayout_13->addWidget(spinBox_Vdev); 657 | 658 | horizontalSpacer_6 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 659 | 660 | horizontalLayout_13->addItem(horizontalSpacer_6); 661 | 662 | label_2 = new QLabel(layoutWidget1); 663 | label_2->setObjectName(QStringLiteral("label_2")); 664 | 665 | horizontalLayout_13->addWidget(label_2); 666 | 667 | spinBox_Sdev = new QSpinBox(layoutWidget1); 668 | spinBox_Sdev->setObjectName(QStringLiteral("spinBox_Sdev")); 669 | spinBox_Sdev->setMinimum(20); 670 | spinBox_Sdev->setMaximum(500); 671 | spinBox_Sdev->setValue(50); 672 | 673 | horizontalLayout_13->addWidget(spinBox_Sdev); 674 | 675 | horizontalSpacer_5 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 676 | 677 | horizontalLayout_13->addItem(horizontalSpacer_5); 678 | 679 | 680 | verticalLayout_6->addLayout(horizontalLayout_13); 681 | 682 | horizontalLayout_16 = new QHBoxLayout(); 683 | horizontalLayout_16->setSpacing(6); 684 | horizontalLayout_16->setObjectName(QStringLiteral("horizontalLayout_16")); 685 | label = new QLabel(layoutWidget1); 686 | label->setObjectName(QStringLiteral("label")); 687 | 688 | horizontalLayout_16->addWidget(label); 689 | 690 | horizontalSliderWhitenSkin = new QSlider(layoutWidget1); 691 | horizontalSliderWhitenSkin->setObjectName(QStringLiteral("horizontalSliderWhitenSkin")); 692 | sizePolicy1.setHeightForWidth(horizontalSliderWhitenSkin->sizePolicy().hasHeightForWidth()); 693 | horizontalSliderWhitenSkin->setSizePolicy(sizePolicy1); 694 | horizontalSliderWhitenSkin->setMinimumSize(QSize(300, 0)); 695 | horizontalSliderWhitenSkin->setMinimum(2); 696 | horizontalSliderWhitenSkin->setMaximum(5); 697 | horizontalSliderWhitenSkin->setValue(5); 698 | horizontalSliderWhitenSkin->setSliderPosition(5); 699 | horizontalSliderWhitenSkin->setOrientation(Qt::Horizontal); 700 | 701 | horizontalLayout_16->addWidget(horizontalSliderWhitenSkin); 702 | 703 | lineEditWhitenSkin = new QLineEdit(layoutWidget1); 704 | lineEditWhitenSkin->setObjectName(QStringLiteral("lineEditWhitenSkin")); 705 | sizePolicy1.setHeightForWidth(lineEditWhitenSkin->sizePolicy().hasHeightForWidth()); 706 | lineEditWhitenSkin->setSizePolicy(sizePolicy1); 707 | lineEditWhitenSkin->setMaximumSize(QSize(60, 16777215)); 708 | 709 | horizontalLayout_16->addWidget(lineEditWhitenSkin); 710 | 711 | 712 | verticalLayout_6->addLayout(horizontalLayout_16); 713 | 714 | 715 | verticalLayout_7->addLayout(verticalLayout_6); 716 | 717 | verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); 718 | 719 | verticalLayout_7->addItem(verticalSpacer); 720 | 721 | tabWidget->addTab(tabFilter, QString()); 722 | tabFix = new QWidget(); 723 | tabFix->setObjectName(QStringLiteral("tabFix")); 724 | lineEditBrushRadiusImageCopy = new QLineEdit(tabFix); 725 | lineEditBrushRadiusImageCopy->setObjectName(QStringLiteral("lineEditBrushRadiusImageCopy")); 726 | lineEditBrushRadiusImageCopy->setGeometry(QRect(410, 390, 51, 20)); 727 | pushButtonMovePatch = new QPushButton(tabFix); 728 | pushButtonMovePatch->setObjectName(QStringLiteral("pushButtonMovePatch")); 729 | pushButtonMovePatch->setGeometry(QRect(10, 450, 75, 23)); 730 | horizontalSliderBrushRadiusImageCopy = new QSlider(tabFix); 731 | horizontalSliderBrushRadiusImageCopy->setObjectName(QStringLiteral("horizontalSliderBrushRadiusImageCopy")); 732 | horizontalSliderBrushRadiusImageCopy->setGeometry(QRect(100, 390, 301, 19)); 733 | horizontalSliderBrushRadiusImageCopy->setMinimum(1); 734 | horizontalSliderBrushRadiusImageCopy->setMaximum(50); 735 | horizontalSliderBrushRadiusImageCopy->setValue(10); 736 | horizontalSliderBrushRadiusImageCopy->setOrientation(Qt::Horizontal); 737 | label_6 = new QLabel(tabFix); 738 | label_6->setObjectName(QStringLiteral("label_6")); 739 | label_6->setGeometry(QRect(10, 360, 71, 16)); 740 | label_7 = new QLabel(tabFix); 741 | label_7->setObjectName(QStringLiteral("label_7")); 742 | label_7->setGeometry(QRect(10, 390, 81, 16)); 743 | label_8 = new QLabel(tabFix); 744 | label_8->setObjectName(QStringLiteral("label_8")); 745 | label_8->setGeometry(QRect(10, 80, 54, 12)); 746 | label_9 = new QLabel(tabFix); 747 | label_9->setObjectName(QStringLiteral("label_9")); 748 | label_9->setGeometry(QRect(10, 150, 61, 16)); 749 | horizontalSliderBrushRadiusImageInpaintHole = new QSlider(tabFix); 750 | horizontalSliderBrushRadiusImageInpaintHole->setObjectName(QStringLiteral("horizontalSliderBrushRadiusImageInpaintHole")); 751 | horizontalSliderBrushRadiusImageInpaintHole->setGeometry(QRect(100, 150, 301, 19)); 752 | horizontalSliderBrushRadiusImageInpaintHole->setMinimum(1); 753 | horizontalSliderBrushRadiusImageInpaintHole->setMaximum(50); 754 | horizontalSliderBrushRadiusImageInpaintHole->setValue(10); 755 | horizontalSliderBrushRadiusImageInpaintHole->setOrientation(Qt::Horizontal); 756 | lineEditBrushRadiusImageInpaintHole = new QLineEdit(tabFix); 757 | lineEditBrushRadiusImageInpaintHole->setObjectName(QStringLiteral("lineEditBrushRadiusImageInpaintHole")); 758 | lineEditBrushRadiusImageInpaintHole->setGeometry(QRect(410, 150, 51, 20)); 759 | pushButtonImageInpaintHoleResult = new QPushButton(tabFix); 760 | pushButtonImageInpaintHoleResult->setObjectName(QStringLiteral("pushButtonImageInpaintHoleResult")); 761 | pushButtonImageInpaintHoleResult->setGeometry(QRect(10, 250, 75, 23)); 762 | label_10 = new QLabel(tabFix); 763 | label_10->setObjectName(QStringLiteral("label_10")); 764 | label_10->setGeometry(QRect(10, 190, 71, 16)); 765 | horizontalSliderBrushRadiusImageInpaintHoleRestrict = new QSlider(tabFix); 766 | horizontalSliderBrushRadiusImageInpaintHoleRestrict->setObjectName(QStringLiteral("horizontalSliderBrushRadiusImageInpaintHoleRestrict")); 767 | horizontalSliderBrushRadiusImageInpaintHoleRestrict->setGeometry(QRect(100, 190, 301, 19)); 768 | horizontalSliderBrushRadiusImageInpaintHoleRestrict->setMinimum(1); 769 | horizontalSliderBrushRadiusImageInpaintHoleRestrict->setMaximum(50); 770 | horizontalSliderBrushRadiusImageInpaintHoleRestrict->setValue(10); 771 | horizontalSliderBrushRadiusImageInpaintHoleRestrict->setOrientation(Qt::Horizontal); 772 | lineEditBrushRadiusImageInpaintHoleRestrict = new QLineEdit(tabFix); 773 | lineEditBrushRadiusImageInpaintHoleRestrict->setObjectName(QStringLiteral("lineEditBrushRadiusImageInpaintHoleRestrict")); 774 | lineEditBrushRadiusImageInpaintHoleRestrict->setGeometry(QRect(410, 190, 51, 20)); 775 | pushButtonImageInpaintHoleRestrictResult = new QPushButton(tabFix); 776 | pushButtonImageInpaintHoleRestrictResult->setObjectName(QStringLiteral("pushButtonImageInpaintHoleRestrictResult")); 777 | pushButtonImageInpaintHoleRestrictResult->setGeometry(QRect(110, 250, 131, 23)); 778 | pushButtonErodeRadius = new QPushButton(tabFix); 779 | pushButtonErodeRadius->setObjectName(QStringLiteral("pushButtonErodeRadius")); 780 | pushButtonErodeRadius->setGeometry(QRect(10, 110, 141, 23)); 781 | spinBoxErodeRadius = new QSpinBox(tabFix); 782 | spinBoxErodeRadius->setObjectName(QStringLiteral("spinBoxErodeRadius")); 783 | spinBoxErodeRadius->setGeometry(QRect(160, 110, 50, 20)); 784 | spinBoxErodeRadius->setMinimumSize(QSize(50, 0)); 785 | spinBoxErodeRadius->setMinimum(0); 786 | spinBoxErodeRadius->setMaximum(5); 787 | pushButtonImageInpaintHoleRestrictResultOut = new QPushButton(tabFix); 788 | pushButtonImageInpaintHoleRestrictResultOut->setObjectName(QStringLiteral("pushButtonImageInpaintHoleRestrictResultOut")); 789 | pushButtonImageInpaintHoleRestrictResultOut->setGeometry(QRect(260, 250, 161, 23)); 790 | comboBox_ifGpu = new QComboBox(tabFix); 791 | comboBox_ifGpu->setObjectName(QStringLiteral("comboBox_ifGpu")); 792 | comboBox_ifGpu->setGeometry(QRect(50, 20, 61, 22)); 793 | comboBox_ifGpu->setEditable(false); 794 | comboBox_ifGpu->setMaxCount(10); 795 | label_11 = new QLabel(tabFix); 796 | label_11->setObjectName(QStringLiteral("label_11")); 797 | label_11->setGeometry(QRect(10, 20, 31, 16)); 798 | pushButton_ClearRestrict = new QPushButton(tabFix); 799 | pushButton_ClearRestrict->setObjectName(QStringLiteral("pushButton_ClearRestrict")); 800 | pushButton_ClearRestrict->setGeometry(QRect(10, 210, 91, 23)); 801 | pushButton_ClearRegion = new QPushButton(tabFix); 802 | pushButton_ClearRegion->setObjectName(QStringLiteral("pushButton_ClearRegion")); 803 | pushButton_ClearRegion->setGeometry(QRect(10, 410, 91, 23)); 804 | tabWidget->addTab(tabFix, QString()); 805 | tabColorMap = new QWidget(); 806 | tabColorMap->setObjectName(QStringLiteral("tabColorMap")); 807 | pushButton_Source = new QPushButton(tabColorMap); 808 | pushButton_Source->setObjectName(QStringLiteral("pushButton_Source")); 809 | pushButton_Source->setGeometry(QRect(60, 70, 75, 23)); 810 | pushButton_Target = new QPushButton(tabColorMap); 811 | pushButton_Target->setObjectName(QStringLiteral("pushButton_Target")); 812 | pushButton_Target->setGeometry(QRect(160, 70, 75, 23)); 813 | pushButton_Result = new QPushButton(tabColorMap); 814 | pushButton_Result->setObjectName(QStringLiteral("pushButton_Result")); 815 | pushButton_Result->setGeometry(QRect(60, 140, 75, 23)); 816 | pushButton_ResultGrayToRGB = new QPushButton(tabColorMap); 817 | pushButton_ResultGrayToRGB->setObjectName(QStringLiteral("pushButton_ResultGrayToRGB")); 818 | pushButton_ResultGrayToRGB->setGeometry(QRect(160, 140, 75, 23)); 819 | tabWidget->addTab(tabColorMap, QString()); 820 | 821 | gridLayout_2->addWidget(tabWidget, 0, 1, 1, 1); 822 | 823 | ImageWorkShopClass->setCentralWidget(centralWidget); 824 | menuBar = new QMenuBar(ImageWorkShopClass); 825 | menuBar->setObjectName(QStringLiteral("menuBar")); 826 | menuBar->setGeometry(QRect(0, 0, 502, 23)); 827 | menuFile = new QMenu(menuBar); 828 | menuFile->setObjectName(QStringLiteral("menuFile")); 829 | menuStage = new QMenu(menuBar); 830 | menuStage->setObjectName(QStringLiteral("menuStage")); 831 | ImageWorkShopClass->setMenuBar(menuBar); 832 | mainToolBar = new QToolBar(ImageWorkShopClass); 833 | mainToolBar->setObjectName(QStringLiteral("mainToolBar")); 834 | ImageWorkShopClass->addToolBar(Qt::TopToolBarArea, mainToolBar); 835 | statusBar = new QStatusBar(ImageWorkShopClass); 836 | statusBar->setObjectName(QStringLiteral("statusBar")); 837 | ImageWorkShopClass->setStatusBar(statusBar); 838 | 839 | menuBar->addAction(menuFile->menuAction()); 840 | menuBar->addAction(menuStage->menuAction()); 841 | menuFile->addAction(actionOpen); 842 | menuFile->addAction(actionSave_as); 843 | menuStage->addAction(actionStageSave); 844 | menuStage->addAction(actionStageBack); 845 | menuStage->addAction(actionImage_last_saved); 846 | 847 | retranslateUi(ImageWorkShopClass); 848 | 849 | tabWidget->setCurrentIndex(1); 850 | comboBox_Lomo->setCurrentIndex(-1); 851 | comboBox_ifGpu->setCurrentIndex(-1); 852 | 853 | 854 | QMetaObject::connectSlotsByName(ImageWorkShopClass); 855 | } // setupUi 856 | 857 | void retranslateUi(QMainWindow *ImageWorkShopClass) 858 | { 859 | ImageWorkShopClass->setWindowTitle(QApplication::translate("ImageWorkShopClass", "ImageWorkshop", 0)); 860 | actionOpen->setText(QApplication::translate("ImageWorkShopClass", "open", 0)); 861 | actionSave_as->setText(QApplication::translate("ImageWorkShopClass", "save as", 0)); 862 | actionStageSave->setText(QApplication::translate("ImageWorkShopClass", "save", 0)); 863 | actionStageBack->setText(QApplication::translate("ImageWorkShopClass", "back", 0)); 864 | actionCompare->setText(QApplication::translate("ImageWorkShopClass", "compare", 0)); 865 | actionImage_last_saved->setText(QApplication::translate("ImageWorkShopClass", "back image", 0)); 866 | pushButtonMedian->setText(QApplication::translate("ImageWorkShopClass", "median", 0)); 867 | labelVignette->setText(QApplication::translate("ImageWorkShopClass", "vignette", 0)); 868 | labelGauss->setText(QApplication::translate("ImageWorkShopClass", " gauss ", 0)); 869 | pushButtonSharp->setText(QApplication::translate("ImageWorkShopClass", "sharp", 0)); 870 | labelBalance->setText(QApplication::translate("ImageWorkShopClass", "balance", 0)); 871 | labelSaturation->setText(QApplication::translate("ImageWorkShopClass", "saturation", 0)); 872 | pushButtonLiquify->setText(QApplication::translate("ImageWorkShopClass", "liquify", 0)); 873 | pushButtonLiquifyRadius->setText(QApplication::translate("ImageWorkShopClass", "setRadius", 0)); 874 | label_Lomo->setText(QApplication::translate("ImageWorkShopClass", "lomo", 0)); 875 | labelLomoR->setText(QApplication::translate("ImageWorkShopClass", "R_mid", 0)); 876 | labelGauss_3->setText(QApplication::translate("ImageWorkShopClass", "G_mid", 0)); 877 | labelGauss_4->setText(QApplication::translate("ImageWorkShopClass", "B_mid", 0)); 878 | label_5->setText(QApplication::translate("ImageWorkShopClass", "draw skinmask", 0)); 879 | label_4->setText(QApplication::translate("ImageWorkShopClass", "filter radius", 0)); 880 | pushButton_Exfoliating->setText(QApplication::translate("ImageWorkShopClass", "dermabrasion", 0)); 881 | label_3->setText(QApplication::translate("ImageWorkShopClass", "value dev", 0)); 882 | label_2->setText(QApplication::translate("ImageWorkShopClass", "spatial dev", 0)); 883 | label->setText(QApplication::translate("ImageWorkShopClass", "whiten skin", 0)); 884 | tabWidget->setTabText(tabWidget->indexOf(tabFilter), QApplication::translate("ImageWorkShopClass", "filter", 0)); 885 | pushButtonMovePatch->setText(QApplication::translate("ImageWorkShopClass", "move patch", 0)); 886 | label_6->setText(QApplication::translate("ImageWorkShopClass", "patch copy", 0)); 887 | label_7->setText(QApplication::translate("ImageWorkShopClass", "select region", 0)); 888 | label_8->setText(QApplication::translate("ImageWorkShopClass", "inpaint", 0)); 889 | label_9->setText(QApplication::translate("ImageWorkShopClass", "add hole", 0)); 890 | pushButtonImageInpaintHoleResult->setText(QApplication::translate("ImageWorkShopClass", "fill hole", 0)); 891 | label_10->setText(QApplication::translate("ImageWorkShopClass", "add restric", 0)); 892 | pushButtonImageInpaintHoleRestrictResult->setText(QApplication::translate("ImageWorkShopClass", "fill hole in restrict", 0)); 893 | pushButtonErodeRadius->setText(QApplication::translate("ImageWorkShopClass", "set hole erode radius", 0)); 894 | pushButtonImageInpaintHoleRestrictResultOut->setText(QApplication::translate("ImageWorkShopClass", "fill hole out of restrict", 0)); 895 | label_11->setText(QApplication::translate("ImageWorkShopClass", "mode", 0)); 896 | pushButton_ClearRestrict->setText(QApplication::translate("ImageWorkShopClass", "clear restrict", 0)); 897 | pushButton_ClearRegion->setText(QApplication::translate("ImageWorkShopClass", "clear region", 0)); 898 | tabWidget->setTabText(tabWidget->indexOf(tabFix), QApplication::translate("ImageWorkShopClass", "patchmatch", 0)); 899 | pushButton_Source->setText(QApplication::translate("ImageWorkShopClass", "source", 0)); 900 | pushButton_Target->setText(QApplication::translate("ImageWorkShopClass", "target", 0)); 901 | pushButton_Result->setText(QApplication::translate("ImageWorkShopClass", "show result", 0)); 902 | pushButton_ResultGrayToRGB->setText(QApplication::translate("ImageWorkShopClass", "gray2rgb", 0)); 903 | tabWidget->setTabText(tabWidget->indexOf(tabColorMap), QApplication::translate("ImageWorkShopClass", "color map", 0)); 904 | menuFile->setTitle(QApplication::translate("ImageWorkShopClass", "File", 0)); 905 | menuStage->setTitle(QApplication::translate("ImageWorkShopClass", "stage", 0)); 906 | } // retranslateUi 907 | 908 | }; 909 | 910 | namespace Ui { 911 | class ImageWorkShopClass: public Ui_ImageWorkShopClass {}; 912 | } // namespace Ui 913 | 914 | QT_END_NAMESPACE 915 | 916 | #endif // UI_IMAGEWORKSHOP_H 917 | -------------------------------------------------------------------------------- /ImageWorkShop/ImageSharpening.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageSharpening.h" 2 | const int laplacianMask[] = {0, -1, 0, -1, 5, -1, 0, -1, 0}; 3 | //const int laplacianMask[] = {-1, -1, -1, -1, 9, -1, -1, -1, -1}; 4 | void ImageSharp::sharp(cv::Mat &cvimage){ 5 | cv::Mat image(cvimage.size(), CV_8UC3); 6 | cvimage.copyTo(image); 7 | int radius = 1; 8 | for(int row = radius; row < image.size().height - radius; row++){ 9 | for(int col = radius; col < image.size().width - radius; col++){ 10 | int result[3] = {0}; 11 | int k = 0; 12 | for(int i = -radius; i < radius + 1; i++){ 13 | for(int j = -radius; j < radius + 1; j++){ 14 | result[0] += image.at(row + i, col + j).val[0] * laplacianMask[k]; 15 | result[1] += image.at(row + i, col + j).val[1] * laplacianMask[k]; 16 | result[2] += image.at(row + i, col + j).val[2] * laplacianMask[k]; 17 | k++; 18 | } 19 | } 20 | for(int i = 0; i < 3; i++){ 21 | if(result[i] < 0) result[i] = 0; 22 | else if(result[i] > 255) result[i] = 255; 23 | } 24 | cvimage.at(row, col).val[0] = result[0]; 25 | cvimage.at(row, col).val[1] = result[1]; 26 | cvimage.at(row, col).val[2] = result[2]; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ImageWorkShop/ImageSharpening.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGE_SHARPENING_H 2 | #define IMAGE_SHARPENING_H 3 | #include 4 | #include 5 | #include 6 | 7 | //const int laplacianMask[] = {-1, -1, -1, -1, 9, -1, -1, -1, -1}; 8 | //const int laplacianMask[] = {0, -1, 0, -1, 4, -1, 0, -1, 0}; 9 | //const int laplacianMask[] = {-1, -1, -1, -1, 8, -1, -1, -1, -1}; 10 | struct ImageSharp{ 11 | public: 12 | void sharp(cv::Mat &image); 13 | }; 14 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/ImageWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageWidget.h" 2 | ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent){ 3 | 4 | } 5 | ImageWidget::~ImageWidget(){ 6 | 7 | } 8 | 9 | void ImageWidget::loadfile(){ 10 | 11 | } 12 | 13 | void ImageWidget::savefile(){ 14 | 15 | } 16 | 17 | //void paintEvent(QPaintEvent *event){ 18 | // 19 | //} -------------------------------------------------------------------------------- /ImageWorkShop/ImageWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEWIDGET_H 2 | #define IMAGEWIDGET_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | //#include 8 | 9 | class ImageWidget : public QWidget 10 | { 11 | Q_OBJECT 12 | public: 13 | ImageWidget(QWidget *parent = 0); 14 | ~ImageWidget(); 15 | 16 | protected: 17 | //void paintEvent(QPaintEvent *event); 18 | //void mousePressEvent(QMouseEvent *event); 19 | 20 | private: 21 | void draw(); 22 | void readRawData(); 23 | 24 | QImage image; 25 | QImage origin_image; 26 | 27 | 28 | public slots: 29 | void loadfile(); 30 | void savefile(); 31 | 32 | }; 33 | 34 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/ImageWorkShop.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {B12702AD-ABFB-343A-A199-8E24837244A3} 23 | Qt4VSv1.0 24 | 25 | 26 | 27 | Application 28 | v110 29 | 30 | 31 | Application 32 | v110 33 | 34 | 35 | Application 36 | v110 37 | 38 | 39 | Application 40 | v110 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | <_ProjectFileVersion>11.0.50727.1 60 | 61 | 62 | $(SolutionDir)$(Platform)\$(Configuration)\ 63 | 64 | 65 | $(SolutionDir)$(Platform)\$(Configuration)\ 66 | 67 | 68 | $(SolutionDir)$(Platform)\$(Configuration)\ 69 | 70 | 71 | $(SolutionDir)$(Platform)\$(Configuration)\ 72 | 73 | 74 | 75 | UNICODE;WIN32;QT_LARGEFILE_SUPPORT;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) 76 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;D:\SDK\opencv\sources\include;$(OPENCLDIR)\inc;%(AdditionalIncludeDirectories) 77 | Disabled 78 | ProgramDatabase 79 | MultiThreadedDebugDLL 80 | true 81 | 82 | 83 | Windows 84 | $(OutDir)\$(ProjectName).exe 85 | $(QTDIR)\lib;D:\SDK\opencv\build\lib\Debug;$(OPENCLDIR)\lib\$(Platform);%(AdditionalLibraryDirectories) 86 | true 87 | qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;opencv_calib3d249d.lib;opencv_contrib249d.lib;opencv_ts249d.lib;opencv_superres249d.lib;opencv_ocl249d.lib;opencv_ml249d.lib;opencv_highgui249d.lib;opencv_core249d.lib;opencv_imgproc249d.lib;opencv_objdetect249d.lib;OpenCL.lib;%(AdditionalDependencies) 88 | 89 | 90 | 91 | 92 | UNICODE;WIN32;QT_LARGEFILE_SUPPORT;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) 93 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) 94 | Disabled 95 | ProgramDatabase 96 | MultiThreadedDebugDLL 97 | true 98 | 99 | 100 | Windows 101 | $(OutDir)\$(ProjectName).exe 102 | $(QTDIR)\lib;%(AdditionalLibraryDirectories) 103 | true 104 | qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) 105 | 106 | 107 | 108 | 109 | UNICODE;WIN32;QT_LARGEFILE_SUPPORT;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) 110 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;D:\SDK\opencv2.4.11\opencv\build\include;$(OPENCLDIR)\inc;%(AdditionalIncludeDirectories) 111 | 112 | MultiThreadedDLL 113 | true 114 | 115 | 116 | Windows 117 | $(OutDir)\$(ProjectName).exe 118 | $(QTDIR)\lib;D:\SDK\opencv2.4.11\opencv\build\x86\vc11\lib;$(OPENCLDIR)\lib\$(Platform);%(AdditionalLibraryDirectories) 119 | true 120 | qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;opencv_calib3d2411.lib;opencv_contrib2411.lib;opencv_ts2411.lib;opencv_superres2411.lib;opencv_ocl2411.lib;opencv_ml2411.lib;opencv_highgui2411.lib;opencv_core2411.lib;opencv_imgproc2411.lib;OpenCL.lib;%(AdditionalDependencies) 121 | 122 | 123 | 124 | 125 | UNICODE;WIN32;QT_LARGEFILE_SUPPORT;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) 126 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) 127 | 128 | MultiThreadedDLL 129 | true 130 | 131 | 132 | Windows 133 | $(OutDir)\$(ProjectName).exe 134 | $(QTDIR)\lib;%(AdditionalLibraryDirectories) 135 | false 136 | qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies) 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | true 147 | true 148 | 149 | 150 | true 151 | true 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | true 165 | true 166 | 167 | 168 | true 169 | true 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | $(QTDIR)\bin\moc.exe;%(FullPath) 188 | Moc%27ing imageworkshop.h... 189 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 190 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-ID:\SDK\opencv\sources\include" "-I$(OPENCLDIR)\inc" 191 | $(QTDIR)\bin\moc.exe;%(FullPath) 192 | Moc%27ing imageworkshop.h... 193 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 194 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" 195 | $(QTDIR)\bin\moc.exe;%(FullPath) 196 | Moc%27ing imageworkshop.h... 197 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 198 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-ID:\SDK\opencv2.4.11\opencv\build\include" "-I$(OPENCLDIR)\inc" 199 | $(QTDIR)\bin\moc.exe;%(FullPath) 200 | Moc%27ing imageworkshop.h... 201 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 202 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" 203 | 204 | 205 | 206 | 207 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 208 | Uic%27ing %(Identity)... 209 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 210 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 211 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 212 | Uic%27ing %(Identity)... 213 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 214 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 215 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 216 | Uic%27ing %(Identity)... 217 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 218 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 219 | $(QTDIR)\bin\uic.exe;%(AdditionalInputs) 220 | Uic%27ing %(Identity)... 221 | .\GeneratedFiles\ui_%(Filename).h;%(Outputs) 222 | "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)" 223 | Designer 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | $(QTDIR)\bin\moc.exe;%(FullPath) 243 | Moc%27ing ImageWidget.h... 244 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 245 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-ID:\SDK\opencv\sources\include" "-I$(OPENCLDIR)\inc" 246 | $(QTDIR)\bin\moc.exe;%(FullPath) 247 | Moc%27ing ImageWidget.h... 248 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 249 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" 250 | $(QTDIR)\bin\moc.exe;%(FullPath) 251 | Moc%27ing ImageWidget.h... 252 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 253 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-ID:\SDK\opencv2.4.11\opencv\build\include" "-I$(OPENCLDIR)\inc" 254 | $(QTDIR)\bin\moc.exe;%(FullPath) 255 | Moc%27ing ImageWidget.h... 256 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp 257 | "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" 258 | 259 | 260 | 261 | 262 | %(FullPath);%(AdditionalInputs) 263 | Rcc%27ing %(Identity)... 264 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 265 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 266 | %(FullPath);%(AdditionalInputs) 267 | Rcc%27ing %(Identity)... 268 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 269 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 270 | %(FullPath);%(AdditionalInputs) 271 | Rcc%27ing %(Identity)... 272 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 273 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 274 | %(FullPath);%(AdditionalInputs) 275 | Rcc%27ing %(Identity)... 276 | .\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs) 277 | "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /ImageWorkShop/ImageWorkShop.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;cxx;c;def 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h 11 | 12 | 13 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 14 | ui 15 | 16 | 17 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 18 | qrc;* 19 | false 20 | 21 | 22 | {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} 23 | moc;h;cpp 24 | False 25 | 26 | 27 | {e8eeb429-891e-4fc2-915f-db30f4b46091} 28 | cpp;moc 29 | False 30 | 31 | 32 | {0b1f08ba-c9da-4fcd-99ae-99bf66f13724} 33 | cpp;moc 34 | False 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Generated Files\Debug 46 | 47 | 48 | Generated Files\Release 49 | 50 | 51 | Generated Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Generated Files\Debug 58 | 59 | 60 | Generated Files\Release 61 | 62 | 63 | Source Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | Source Files 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | 109 | 110 | Header Files 111 | 112 | 113 | Form Files 114 | 115 | 116 | Resource Files 117 | 118 | 119 | Header Files 120 | 121 | 122 | 123 | 124 | Header Files 125 | 126 | 127 | Header Files 128 | 129 | 130 | Header Files 131 | 132 | 133 | Header Files 134 | 135 | 136 | Header Files 137 | 138 | 139 | Header Files 140 | 141 | 142 | Header Files 143 | 144 | 145 | Header Files 146 | 147 | 148 | Header Files 149 | 150 | 151 | Header Files 152 | 153 | 154 | Header Files 155 | 156 | 157 | Header Files 158 | 159 | 160 | Header Files 161 | 162 | 163 | Header Files 164 | 165 | 166 | -------------------------------------------------------------------------------- /ImageWorkShop/Liquify.cpp: -------------------------------------------------------------------------------- 1 | #include "Liquify.h" 2 | #include 3 | #include 4 | using namespace std; 5 | Liquify::Liquify(){ 6 | mask = NULL; 7 | radius = 20; 8 | centerX = 0; 9 | centerY = 0; 10 | genMask(); 11 | } 12 | 13 | Liquify::~Liquify(){ 14 | if(mask != NULL) 15 | delete mask; 16 | } 17 | 18 | void Liquify::genMask(){ 19 | if(mask != NULL) 20 | delete mask; 21 | mask = new char[(radius * 2 + 1) * (radius * 2 + 1)]; 22 | for(int x = 0; x < radius * 2 + 1; x++){ 23 | for(int y = 0; y < radius * 2 + 1; y++){ 24 | mask[x * (2 * radius + 1) + y] = 1; 25 | } 26 | } 27 | 28 | int centerx = radius; 29 | int centery = radius; 30 | for(int y = 0; y < centery; y++){ 31 | for(int x = 0; x < centerx - y; x++){ 32 | int r = (x - centerx) * (x - centerx) + (y - centery) * (y - centery); 33 | if(r > radius * radius){ 34 | mask[y * (2 * radius + 1) + x] = 0; 35 | mask[y * (2 * radius + 1) + 2 * radius - x] = 0; 36 | mask[(2 * radius - y) * (2 * radius + 1) + x] = 0; 37 | mask[(2 * radius - y) * (2 * radius + 1) + 2 * radius - x] = 0; 38 | } 39 | 40 | } 41 | } 42 | 43 | for(int y = 0; y < centery + 1; y++){ 44 | for(int x = 0; x < centerx + 1 - y; x++){ 45 | short gx = 1, gy = 1; 46 | if(x > 0) 47 | gx = mask[y * (2 * radius + 1) + x] - mask[y * (2 * radius + 1) + x - 1]; 48 | if(y > 0) 49 | gy = mask[y * (2 * radius + 1) + x] - mask[(y - 1) * (2 * radius + 1) + x]; 50 | if(gx * mask[y * (2 * radius + 1) + x] > 0 || gy * mask[y * (2 * radius + 1) + x] > 0){ 51 | mask[y * (2 * radius + 1) + x] = 2; 52 | mask[y * (2 * radius + 1) + 2 * radius - x] = 2; 53 | mask[(2 * radius - y) * (2 * radius + 1) + x] = 2; 54 | mask[(2 * radius - y) * (2 * radius + 1) + 2 * radius - x] = 2; 55 | //break; 56 | } 57 | 58 | } 59 | } 60 | } 61 | 62 | 63 | void Liquify::liquify(cv::Mat &image, int strength, int pointX, int pointY){ 64 | cv::Mat img(image.size(), CV_64F); 65 | image.copyTo(img); 66 | int vecX = pointX - centerX; 67 | int vecY = pointY - centerY; 68 | int newX; 69 | int newY; 70 | double dX,dY; 71 | 72 | //const char filename[] = "mytext.txt"; 73 | // ofstream o_file; 74 | // string out_text; 75 | 76 | //д 77 | //o_file.open(filename); 78 | 79 | 80 | double xadd; 81 | double yadd; 82 | 83 | 84 | for(int row = -radius; row < radius + 1; row++){ 85 | for(int col = -radius; col < radius + 1; col++){ 86 | if(centerX + col < 0 || centerY + row < 0 || centerX + col >= image.cols || centerY + row >= image.rows) 87 | continue; 88 | if(mask[(row + radius) * (2 * radius + 1) + col + radius] > 0){ 89 | double p = radius * radius - row * row - col * col; 90 | p = p * 1.0 / (p + radius * radius + 1 * (vecX * vecX + vecY * vecY)); 91 | p = p * p; 92 | dX = col - p * vecX; 93 | dY = row - p * vecY; 94 | newX = (int)(col - p * vecX); 95 | newY = (int)(row - p * vecY); 96 | if(centerX + newX < 0 || centerY + newY < 0 || centerX + newX >= image.cols || centerY + newY >= image.rows) 97 | continue; 98 | xadd = 1; 99 | yadd = 1; 100 | 101 | if(dX < 0) xadd = -1; 102 | if(dY < 0) yadd = -1; 103 | 104 | if(centerX + newX + xadd < 0 || centerX + newX + xadd >= image.cols || centerY + newY + yadd < 0 || centerY + newY + yadd >= image.rows) 105 | continue; 106 | 107 | double x1 = (dX - newX) * xadd; 108 | double y1 = (dY - newY) * yadd; 109 | cv::Vec3b cross1 = img.at(centerY + newY, centerX + newX) * (1 - y1) + img.at(centerY + newY + yadd, centerX + newX) * y1; 110 | cv::Vec3b cross2 = img.at(centerY + newY, centerX + newX + xadd) * (1 - y1) + img.at(centerY + newY + yadd, centerX + newX + xadd) * y1; 111 | image.at(centerY + row, centerX + col) = cross1 * (1 - x1) + cross2 * x1; 112 | //image.at(centerY + row, centerX + col) = img.at(centerY + newY, centerX + newX); 113 | 114 | } 115 | } 116 | } 117 | //o_file.close(); 118 | } 119 | 120 | 121 | void Liquify::addCircle(cv::Mat &img){ 122 | img.rows = image.rows; 123 | img.cols = image.cols; 124 | img.dims = image.dims; 125 | image.copyTo(img); 126 | for(int row = -radius; row < radius + 1; row++){ 127 | for(int col = -radius; col < radius + 1; col++){ 128 | if(centerX + col < 0 || centerY + row < 0 || centerX + col >= image.cols || centerY + row >= image.rows) 129 | continue; 130 | if(mask[(row + radius) * (2 * radius + 1) + col + radius] == 2){ 131 | img.at(centerY + row, centerX + col).val[0] = 255; 132 | img.at(centerY + row, centerX + col).val[1] = 255; 133 | img.at(centerY + row, centerX + col).val[2] = 255; 134 | } 135 | } 136 | } 137 | } -------------------------------------------------------------------------------- /ImageWorkShop/Liquify.h: -------------------------------------------------------------------------------- 1 | #ifndef LIQUIFY_H 2 | #define LIQUIFY_H 3 | #include 4 | #include 5 | #include 6 | class Liquify{ 7 | public: 8 | char *mask; 9 | int radius; 10 | int centerX, centerY; 11 | cv::Mat image; 12 | Liquify(); 13 | ~Liquify(); 14 | void genMask(); 15 | void addCircle(cv::Mat &img); 16 | void liquify(cv::Mat &image, int strength, int pointX, int pointY); 17 | private: 18 | }; 19 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/Lomo.cpp: -------------------------------------------------------------------------------- 1 | #include "Lomo.h" 2 | #include 3 | Lomo::Lomo(){ 4 | for(int i = 0; i < 256; i++) 5 | LinearTable[i] = i; 6 | } 7 | void Lomo::Sepia(cv::Mat &image){ 8 | //cv::Mat img(image.size(), CV_64F); 9 | //image.copyTo(img); 10 | int bb, bg, br; 11 | int mb, mg, mr; 12 | for(int row = 0; row < image.rows; row++){ 13 | for(int col = 0; col < image.cols; col++){ 14 | bb = image.at(row, col).val[0]; 15 | bg = image.at(row, col).val[1]; 16 | br = image.at(row, col).val[2]; 17 | mr = (101 * br + 197 * bg + 48 * bb) >> 8; 18 | mg = (89 * br + 176 * bg + 43 * bb) >> 8; 19 | mb = (70 * br + 137 * bg + 34 * bb) >> 8; 20 | if(mr > 255) mr = 255; 21 | if(mr < 0) mr = 0; 22 | if(mg > 255) mg = 255; 23 | if(mg < 0) mg = 0; 24 | if(mb > 255) mb = 255; 25 | if(mb < 0) mb = 0; 26 | image.at(row, col).val[0] = mb; 27 | image.at(row, col).val[1] = mg; 28 | image.at(row, col).val[2] = mr; 29 | } 30 | } 31 | } 32 | 33 | void Lomo::Carving(cv::Mat &image){ 34 | cv::Mat img(image.size(), CV_64F); 35 | image.copyTo(img); 36 | int bb, bg, br; 37 | for(int row = 0; row < image.rows; row++){ 38 | for(int col = 0; col < image.cols; col++){ 39 | if(row + 1 == image.rows) 40 | continue; 41 | bb = image.at(row, col).val[0] - image.at(row + 1, col).val[0] + 127; 42 | bg = image.at(row, col).val[1] - image.at(row + 1, col).val[1] + 127; 43 | br = image.at(row, col).val[2] - image.at(row + 1, col).val[2] + 127; 44 | if(br > 255) br = 255; 45 | if(br < 0) br = 0; 46 | if(bg > 255) bg = 255; 47 | if(bg < 0) bg = 0; 48 | if(bb > 255) bb = 255; 49 | if(bb < 0) bb = 0; 50 | image.at(row, col).val[0] = bb; 51 | image.at(row, col).val[1] = bg; 52 | image.at(row, col).val[2] = br; 53 | } 54 | } 55 | } 56 | 57 | void Lomo::Pencil(cv::Mat &image){ 58 | cv::Mat gray(image.size(), CV_64F); 59 | cv::Mat img(image.size(), CV_64F); 60 | //cv::Mat img; 61 | int gray_sv = 30; 62 | cv::cvtColor(image, gray, CV_BGR2GRAY); 63 | cv::cvtColor(gray, img, CV_GRAY2BGR); 64 | int v1, v2, v3, v4, v5, v6, v7, v8; 65 | for(int row = 0; row < image.rows; row++){ 66 | for(int col = 0; col < image.cols; col++){ 67 | if(row - 1 < 0 || row + 1 >= image.rows || col - 1 < 0 || col + 1 >= image.cols){ 68 | image.at(row, col).val[0] = img.at(row, col).val[0]; 69 | image.at(row, col).val[1] = img.at(row, col).val[1]; 70 | image.at(row, col).val[2] = img.at(row, col).val[2]; 71 | } 72 | else{ 73 | v1 = abs(img.at(row, col).val[0] - img.at(row + 1, col).val[0]); 74 | v2 = abs(img.at(row, col).val[0] - img.at(row + 1, col + 1).val[0]); 75 | v3 = abs(img.at(row, col).val[0] - img.at(row + 1, col - 1).val[0]); 76 | v4 = abs(img.at(row, col).val[0] - img.at(row - 1, col).val[0]); 77 | v5 = abs(img.at(row, col).val[0] - img.at(row - 1, col + 1).val[0]); 78 | v6 = abs(img.at(row, col).val[0] - img.at(row - 1, col - 1).val[0]); 79 | v7 = abs(img.at(row, col).val[0] - img.at(row, col + 1).val[0]); 80 | v8 = abs(img.at(row, col).val[0] - img.at(row, col - 1).val[0]); 81 | if(v1 > gray_sv || v2 > gray_sv || v3 > gray_sv || v4 > gray_sv || v5 > gray_sv || v6 > gray_sv || v7 > gray_sv || v8 > gray_sv){ 82 | image.at(row, col).val[0] = 0; 83 | image.at(row, col).val[1] = 0; 84 | image.at(row, col).val[2] = 0; 85 | } 86 | else{ 87 | image.at(row, col).val[0] = 255; 88 | image.at(row, col).val[1] = 255; 89 | image.at(row, col).val[2] = 255; 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | void Lomo::Desaturate(cv::Mat &image) 97 | { 98 | int min, max, mean; 99 | int b, g, r; 100 | for(int row = 0; row < image.rows; row++){ 101 | for(int col = 0; col < image.cols; col++){ 102 | if(row + 1 == image.rows) 103 | continue; 104 | b = image.at(row, col).val[0]; 105 | g = image.at(row, col).val[1]; 106 | r = image.at(row, col).val[2]; 107 | if(b > g){ 108 | max = b; 109 | min = g; 110 | } 111 | else{ 112 | max = g; 113 | min = b; 114 | } 115 | if(r > max) 116 | max = r; 117 | if(r < min) 118 | min = r; 119 | 120 | mean = (max + min) >> 1; 121 | 122 | image.at(row, col).val[0] = mean; 123 | image.at(row, col).val[1] = mean; 124 | image.at(row, col).val[2] = mean; 125 | } 126 | } 127 | } 128 | 129 | void Lomo::Sepia2(cv::Mat &image){ 130 | Desaturate(image); 131 | Level(image, BLUE, 0, 152, 255, 0, 255); 132 | Level(image, RED, 0, 101, 255, 0, 255); 133 | } 134 | void Lomo::GetLevelTable(unsigned char * Table, unsigned char InputLeftLimit, unsigned char InputMiddle, unsigned char InputRightLimit, unsigned char OutputLeftLimit , unsigned char OutputRightLimit) 135 | { 136 | if (InputLeftLimit > 253) InputLeftLimit = 253; 137 | if (InputLeftLimit < 0) InputLeftLimit = 0; 138 | if (InputRightLimit > 255)InputRightLimit = 255; 139 | if (InputRightLimit < 2) InputRightLimit = 2; 140 | if (InputMiddle > 254)InputMiddle = 254; 141 | if (InputMiddle < 1)InputMiddle = 1; 142 | if (InputMiddle > InputRightLimit)InputMiddle = InputRightLimit - 1; 143 | if (InputMiddle < InputLeftLimit)InputMiddle = InputLeftLimit + 1; 144 | if (OutputLeftLimit < 0)OutputLeftLimit = 0; 145 | if (OutputLeftLimit > 255)OutputLeftLimit = 255; 146 | if (OutputRightLimit < 0)OutputRightLimit = 0; 147 | if (OutputRightLimit > 255)OutputRightLimit = 255; 148 | 149 | for (int Index = 0; Index <= 255; Index++) 150 | { 151 | double Temp = Index - InputLeftLimit; 152 | if (Temp < 0) 153 | { 154 | Temp = OutputLeftLimit; 155 | } 156 | else if (Temp + InputLeftLimit > InputRightLimit) 157 | { 158 | Temp = OutputRightLimit; 159 | } 160 | else 161 | { 162 | double Gamma = log(0.5) / log((double)(InputMiddle - InputLeftLimit) / (InputRightLimit - InputLeftLimit)); 163 | Temp = OutputLeftLimit + (OutputRightLimit - OutputLeftLimit) * pow((Temp / (InputRightLimit - InputLeftLimit)), Gamma); 164 | } 165 | if (Temp > 255) 166 | Temp = 255; 167 | else if (Temp < 0) 168 | Temp = 0; 169 | Table[Index] = Temp; 170 | } 171 | } 172 | 173 | void Lomo::Curve(cv::Mat &image, unsigned char * TableB, unsigned char * TableG, unsigned char * TableR) 174 | { 175 | cv::Mat img(image.size(), CV_64F); 176 | image.copyTo(img); 177 | 178 | for(int row = 0; row < image.rows; row++){ 179 | for(int col = 0; col < image.cols; col++){ 180 | image.at(row, col).val[0] = TableB[img.at(row, col).val[0]]; 181 | image.at(row, col).val[1] = TableG[img.at(row, col).val[1]]; 182 | image.at(row, col).val[2] = TableR[img.at(row, col).val[2]]; 183 | } 184 | } 185 | } 186 | 187 | void Lomo::Level(cv::Mat &image, CHANNEL channel, unsigned char InputLeftLimit, unsigned char InputMiddle, unsigned char InputRightLimit, unsigned char OutputLeftLimit , unsigned char OutputRightLimit) 188 | { 189 | GetLevelTable(Table, InputLeftLimit,InputMiddle,InputRightLimit,OutputLeftLimit,OutputRightLimit); 190 | switch(channel){ 191 | case RGB: 192 | Curve(image,Table,Table,Table); 193 | break; 194 | case BLUE: 195 | Curve(image,Table,LinearTable,LinearTable); 196 | break; 197 | case GREEN: 198 | Curve(image,LinearTable,Table,LinearTable); 199 | break; 200 | case RED: 201 | Curve(image,LinearTable,LinearTable,Table); 202 | break; 203 | default: 204 | break; 205 | } 206 | } 207 | 208 | void Lomo::lomoStyle1(cv::Mat &image){ 209 | unsigned char TB[256]; 210 | unsigned char TG[256]; 211 | unsigned char TR[256]; 212 | GetLevelTable(TR, 0, 54, 255, 0, 255); 213 | GetLevelTable(TG, 0, 88, 255, 0, 255); 214 | GetLevelTable(TB, 0, 155, 255, 0, 255); 215 | Curve(image, TB, TG, TR); 216 | } -------------------------------------------------------------------------------- /ImageWorkShop/Lomo.h: -------------------------------------------------------------------------------- 1 | #ifndef LOMO_H 2 | #define LOMO_H 3 | #include 4 | #include 5 | #include 6 | enum CHANNEL{RGB, BLUE, GREEN, RED}; 7 | class Lomo{ 8 | public: 9 | Lomo(); 10 | cv::Mat lomoImage; 11 | unsigned char Table[256]; 12 | unsigned char LinearTable[256]; 13 | void lomoStyle1(cv::Mat &image); 14 | void Sepia(cv::Mat &image); 15 | void Sepia2(cv::Mat &image); 16 | void Carving(cv::Mat &image); 17 | void Pencil(cv::Mat &image); 18 | void Curve(cv::Mat &image, unsigned char * TableB, unsigned char * TableG, unsigned char * TableR); 19 | void GetLevelTable(unsigned char * Table, unsigned char InputLeftLimit, unsigned char InputMiddle, unsigned char InputRightLimit, unsigned char OutputLeftLimit , unsigned char OutputRightLimit); 20 | private: 21 | //unsigned char TableB[256]; 22 | //unsigned char TableR[256]; 23 | //unsigned char TableG[256]; 24 | 25 | 26 | void Desaturate(cv::Mat &image); 27 | 28 | void Level(cv::Mat &image, CHANNEL channel, unsigned char InputLeftLimit, unsigned char InputMiddle, unsigned char InputRightLimit, unsigned char OutputLeftLimit , unsigned char OutputRightLimit); 29 | }; 30 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/MedianFilter.cpp: -------------------------------------------------------------------------------- 1 | #include "MedianFilter.h" 2 | void MedianFilter::medianFilter(cv::Mat &cvimage, int radius){ 3 | std::vector recordB((2 * radius + 1) * (2 * radius + 1)); 4 | std::vector recordG((2 * radius + 1) * (2 * radius + 1)); 5 | std::vector recordR((2 * radius + 1) * (2 * radius + 1)); 6 | 7 | cv::Mat image(cvimage.size(), CV_8UC3); 8 | cvimage.copyTo(image); 9 | for(int row = 0; row < image.size().height; row++){ 10 | for(int col = 0; col < image.size().width; col++){ 11 | int k = 0; 12 | for(int i = -radius; i < radius + 1; i++){ 13 | for(int j = -radius; j < radius + 1; j++){ 14 | if(row + i < 0 || row + i > image.size().height - 1 || col + j < 0 || col + j > image.size().width - 1) 15 | continue; 16 | recordB[k] = image.at(row + i, col + j).val[0]; 17 | recordG[k] = image.at(row + i, col + j).val[1]; 18 | recordR[k] = image.at(row + i, col + j).val[2]; 19 | k++; 20 | } 21 | } 22 | QuickSort(&recordB[0], 0 , k); 23 | QuickSort(&recordG[0], 0 , k); 24 | QuickSort(&recordR[0], 0 , k); 25 | cvimage.at(row, col).val[0] = recordB[k / 2]; 26 | cvimage.at(row, col).val[1] = recordG[k / 2]; 27 | cvimage.at(row, col).val[2] = recordR[k / 2]; 28 | } 29 | } 30 | recordB.clear(); 31 | recordG.clear(); 32 | recordR.clear(); 33 | 34 | } 35 | 36 | void MedianFilter::QuickSort(int *sort, int begin, int end) 37 | { 38 | if(begin >= end) return; 39 | int mid = Partition(sort, begin, end); 40 | QuickSort(sort, begin, mid - 1); 41 | QuickSort(sort, mid + 1, end); 42 | } 43 | int MedianFilter::Partition(int *sort, int begin, int end){ 44 | unsigned c; 45 | int i = begin - 1; 46 | for(int j = begin; j < end; j++){ 47 | if(sort[j] <= sort[end]){ 48 | i++; 49 | c = sort[i]; 50 | sort[i] = sort[j]; 51 | sort[j] = c; 52 | } 53 | } 54 | c = sort[i + 1]; 55 | sort[i + 1] = sort[end]; 56 | sort[end] = c; 57 | return i + 1; 58 | } -------------------------------------------------------------------------------- /ImageWorkShop/MedianFilter.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDIANFILTER_H 2 | #define MEDIANFILTER_H 3 | #include 4 | #include 5 | #include 6 | struct MedianFilter{ 7 | public: 8 | MedianFilter(){} 9 | void medianFilter(cv::Mat &image, int radius); 10 | int Partition(int *sort, int begin, int end); 11 | void QuickSort(int *sort, int begin, int end); 12 | }; 13 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/MyPatchMatch.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunsiy10/ImageWorkShop/14013beccab1f7b6894cac92e2f312c2ef622589/ImageWorkShop/MyPatchMatch.cpp -------------------------------------------------------------------------------- /ImageWorkShop/MyPatchMatch.h: -------------------------------------------------------------------------------- 1 | #ifndef MY_PATCH_MATCH_H 2 | #define MY_PATCH_MATCH_H 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #define PATCHRADIUS 2 10 | #define PATCHSIZE 5 11 | 12 | #include 13 | 14 | 15 | 16 | using namespace cv; 17 | enum INTERECTYION{NO, /*HOLE, TARGET, SOURCE,*/ ImageCopy, INPAINT}; 18 | enum ImageCopyMODE{ADDTARGET, MOVE, NO_ImageCopy}; 19 | enum ImageInpaintMODE{INPAINT_NO, INPAINT_HOLE, INPAINT_RESTRICT}; 20 | enum PatchMatchMode{GPU_JUMPFLOODING, CPU}; 21 | class MyPatchMatch{ 22 | public: 23 | int numberOfScales; 24 | int numberOfIterationPerScale; 25 | int imageRows; 26 | int imageCols; 27 | Mat tempImage; 28 | int mouseDownX; 29 | int mouseDownY; 30 | INTERECTYION interection; 31 | MyPatchMatch(); 32 | ~MyPatchMatch(); 33 | 34 | 35 | // old inpaint method 36 | void imageInpaint3(Mat& SourceImageRGB, Mat TargetImageRGB); 37 | void initHole(cv::Mat image, cv::Mat offset); 38 | void pyrDownMask(cv::Mat in, cv::Mat &out); 39 | void pyrUpOffset(Mat in, Mat mask, Mat &out); 40 | void generateHole(Mat& target, Mat source, Mat offset, bool odd); 41 | Vec3f generateHolePixel(Mat& target, Mat source, Mat offset, int pixel_row, int pixel_col, bool odd); 42 | Vec3f getMeanHolePixel(float* weight, Vec3f* pixels, int length, bool odd); 43 | void randomSearchHole(Mat source, Mat target, Mat& offest, int row, int col); 44 | void propagationHole(Mat source, Mat target, Mat& offest, int row, int col, bool odd); 45 | void randomSearch(Mat source, Mat target, Mat& offest); 46 | void propagation(Mat source, Mat target, Mat& offest, bool odd); 47 | void vote2(Mat source, Mat offset, Mat &result, Mat mask); 48 | float computeDistance(Mat A, Mat B); 49 | float computeDistanceWithHole(Mat A, Mat B, Mat offset, int low_row, int left_col); 50 | Mat getPatch(int topLeftX, int topLeftY, Mat source); 51 | void scale(Mat& image, int scaleTime); 52 | void initialOffset(Mat &offset, bool ifReserve); 53 | 54 | 55 | // old image copy 56 | double w; 57 | int oldTopLeftX, oldTopLeftY; 58 | int newTopLeftX, newTopLeftY; 59 | int ImageCopyRadius; 60 | char *ImageCopyMask; 61 | ImageCopyMODE ImageCopyMode; 62 | bool selectImageCopyPatch; 63 | bool ImageCopyMoveStart; 64 | 65 | void vote(Mat source, Mat offset, Mat &result); 66 | void getAndShowImageCopyMovedImage(int ax, int ay, Mat& image, bool ifImageCopy); 67 | void addToImageCopyMask(int ax, int ay, int rows, int cols); 68 | void zeroImageCopyMask(int length, bool newImage); 69 | Rect getImageCopyMaskRect(); 70 | void showImageCopyMaskImage(Mat &image); 71 | void imageImageCopy(Mat& SourceImageRGB, Mat TargetImageRGB); 72 | void imageImageCopy2(Mat& SourceImageRGB, Mat TargetImageRGB); 73 | void updateOffset(Mat& offsetMap, Mat newOffsetMap, Mat target, Mat source); 74 | void expandOffset(Mat oldOffset, Mat& newOffset); 75 | Mat displayRegartImage(Mat& Image, Size orgSize); 76 | void addCircleToImage(cv::Mat &image, int ax, int ay); 77 | 78 | 79 | 80 | //new inpaint method 81 | Mat currentRestrict; 82 | double *similarity; 83 | int ImageInpaintRadius; 84 | int ImageInpaintRestrictRadius; 85 | int patch_radius; 86 | int restrictUp, restrictDown, restrictLeft, restrictRight; 87 | int erodeRadius; 88 | ImageInpaintMODE ImageInpaintMode; 89 | ImageInpaintMODE ImageInpaintModeWhenWork; 90 | 91 | 92 | 93 | void imageInpaint(Mat& SourceImageRGB, Mat TargetImageRGB); 94 | void imageInpaintWithRestrict(Mat& SourceImageRGB, Mat TargetImageRGB, char* holeInRestrict); 95 | void pyDownSource(Mat& source, Mat& mask, Mat& newMask); 96 | void pyUpTarget(Mat& oldTarget, Mat& newTarget); 97 | int getHoleCount(Mat& source); 98 | void initialOffset(Mat source, Mat target, Mat mask, Mat &Offset, Mat& dis); 99 | void updatePixelNNF(Mat source, Mat target, Mat offset, Mat mask, int row, int col, bool odd, Mat& currentDistance); 100 | int computeDistance(Mat source, int srow, int scol, Mat target, int trow, int tcol, Mat mask); 101 | void vote(Mat source, Mat target, Mat& offset, Mat mask, bool upscale, Mat& distance); 102 | void pyUpOffset(Mat source, Mat target, Mat mask, Mat& oldOff, Mat& newOff, Mat ¤tDistance); 103 | void initialSimilarity(); 104 | void deleteSimilarity(); 105 | void debugoffsettxt(Mat Offset, Mat dis); 106 | void showImageInpaintRestrictMaskImage(Mat &image); 107 | char *InpaintRestrictMask; 108 | void erodeMask(int rows, int cols); 109 | void imageInpaint2(Mat& SourceImageRGB, Mat TargetImageRGB); 110 | void showTempImage(Mat image, Size originSize); 111 | char *ImageInpaintMask; 112 | void getRestrictPos(); 113 | void addToImageInpaintMask(int ax, int ay, int rows, int cols); 114 | void addToImageInpaintRestrictMask(int ax, int ay, int rows, int cols); 115 | void zeroInpaintMask(int length, bool newImage); 116 | void initialImageInpaintOffset(Mat &offset, Mat mask); 117 | void setOffsetMask(Mat &offset, Mat mask); 118 | void showImageInpaintMaskImage(Mat &image); 119 | void addCircleToImageInpaint(cv::Mat &image, int ax, int ay); 120 | 121 | 122 | //new copy method 123 | void imageInpaintCopy(Mat& SourceImageRGB, Mat TargetImageRGB); 124 | void initialCopyOffset(Mat &offset, Mat &mask); 125 | void conputeImageDistance(Mat source, Mat target, Mat mask, Mat &Offset, Mat& dis); 126 | void pyUpOffsetCopy(Mat source, Mat target, Mat mask, Mat& oldOff, Mat& newOff, Mat ¤tDistance); 127 | void pyDownOffset(Mat& newoff, Mat& oldoff); 128 | void pyDownOffset(Mat& newOff, Mat& oldOff, Mat& oldmask, Mat& newmask); 129 | void pyDownSourceCopy(Mat& source, Mat& mask, Mat& newMask); 130 | void expandOffsetCopy(Mat oldOffset, Mat& newOffset); 131 | 132 | 133 | //interact 134 | void dealWithImageInpaintMouseMoveEvent(int ax, int ay, Mat &image); 135 | void dealWithImageInpaintMouseButtonDown(int ax, int ay, Mat &image); 136 | void dealWithImageInpaintMouseButtonUp(int ax, int ay, Mat &image); 137 | 138 | void dealWithImageCopyMouseMoveEvent(int ax, int ay, Mat &image); 139 | void dealWithImageCopyMouseMoveButtonDown(int ax, int ay, Mat &image); 140 | bool dealWithImageCopyMouseMoveButtonUp(int ax, int ay, Mat &image); 141 | 142 | 143 | //for debug 144 | bool debugOffset(Mat& offset); 145 | bool debugShowOffset(string name, Mat offset); 146 | void debugImage(Mat &Image, char * name); 147 | void debugMat(Mat mat); 148 | 149 | 150 | //opencl 151 | PatchMatchMode mode; 152 | vector platforms; 153 | vector device_id; 154 | cl_context contextCl; 155 | cl_command_queue clQueue; 156 | 157 | cl_program jumpFloodingProgram; 158 | cl_program jumpFloodingCopyProgram; 159 | cl_program jumpFloodingRestrictProgram; 160 | 161 | cl_kernel jumpFloodingKernel; 162 | cl_kernel jumpFloodingCopyKernel; 163 | cl_kernel jumpFloodingRestrictKernel; 164 | 165 | cl_int buildProgram(char* filename, char* kernel_name, cl_kernel& kernel, cl_program &program); 166 | void initOpencl(); 167 | void destroyOpencl(); 168 | 169 | void imageInpaintCL_JF(Mat& SourceImageRGB, Mat TargetImageRGB); 170 | void imageInpaintCL_JF_TEST(Mat& SourceImageRGB, Mat TargetImageRGB); 171 | 172 | void imageInpaintCopyCL_JF(Mat& SourceImageRGB, Mat TargetImageRGB); 173 | 174 | void imageInpaintWithRestrictCL_JF(Mat& SourceImageRGB, Mat TargetImageRGB, char* holeInRestrict); 175 | 176 | void jumpFloodingCopy(Mat source, Mat target, Mat offset[], Mat mask, Mat currentDistance[], int KNNnum); 177 | void jumpFlooding(Mat source, Mat target, Mat offset[], Mat mask, Mat currentDistance[], int KNNnum); 178 | void jumpFloodingRestrict(Mat source, Mat target, Mat offset[], Mat mask, Mat currentDistance[], Mat restrict, int KNNnum); 179 | 180 | 181 | void jumpFloodingCPU(Mat source, Mat target, Mat offset[], Mat mask, Mat currentDistance[], int KNNnum); 182 | }; 183 | 184 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/PatchMatch.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunsiy10/ImageWorkShop/14013beccab1f7b6894cac92e2f312c2ef622589/ImageWorkShop/PatchMatch.cpp -------------------------------------------------------------------------------- /ImageWorkShop/PatchMatch.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCH_MATCH_H 2 | #define PATCH_MATCH_H 3 | #include 4 | #include 5 | #include 6 | 7 | #define XY_TO_INT(x, y) (((y)<<12)|(x)) 8 | #define INT_TO_X(v) ((v)&((1<<12)-1)) 9 | #define INT_TO_Y(v) ((v)>>12) 10 | 11 | #define patch_w 18 12 | 13 | class BITMAP { public: 14 | int w, h; 15 | int *data; 16 | BITMAP(int w_, int h_) :w(w_), h(h_) { 17 | data = new int[w*h]; 18 | for(int i = 0; i < w*h; i++) 19 | data[i] = 0; 20 | } 21 | ~BITMAP() { delete[] data; } 22 | int *operator[](int y) { return &data[y*w]; } 23 | }; 24 | 25 | class PatchMatch{ 26 | public: 27 | int holeRadius; 28 | int targetRadius; 29 | int targetCount; 30 | int sourceRadius; 31 | 32 | char* sourceMask; 33 | char* targetMask; 34 | PatchMatch(){ 35 | holeRadius = 10; 36 | targetRadius = 10; 37 | sourceRadius = 10; 38 | targetMask = NULL; 39 | sourceMask = NULL; 40 | } 41 | void patchmatch(cv::Mat &a, cv::Mat &b, BITMAP *ann, BITMAP &annd); 42 | void patchmatch(cv::Mat &a, cv::Mat &b, BITMAP *&ann, BITMAP *&annd); 43 | void vote(cv::Mat &target, cv::Mat &source, BITMAP *ann); 44 | void zeroMask(int length, bool newImage); 45 | void addToTargetMask(int ax, int ay, int rows, int cols); 46 | void addToSourceMask(int ax, int ay, int rows, int cols); 47 | void updateSourceMask(int rows, int cols); 48 | void getSourceImageFromSourceMask(cv::Mat &image, cv::Mat &sourceImage); 49 | void addMaskToImage(cv::Mat &image); 50 | bool checkTargetMask(int length); 51 | bool checkSourceMask(int length); 52 | private: 53 | int dist(cv::Mat &a, cv::Mat &b, int ax, int ay, int bx, int by, int cutoff); 54 | void improve_guess(cv::Mat &a, cv::Mat &b, int ax, int ay, int &xbest, int &ybest, int &dbest, int bx, int by); 55 | 56 | 57 | 58 | }; 59 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/Saturation.cpp: -------------------------------------------------------------------------------- 1 | #include "Saturation.h" 2 | 3 | void Saturation::saturation(cv::Mat &image, double increment){ 4 | cv::Mat img(image.size(), CV_64F); 5 | image.copyTo(img); 6 | int b, g, r, max, min; 7 | double delta, value, L, S, alpha; 8 | 9 | for(int row = 0; row < image.rows; row++){ 10 | for(int col = 0; col < image.cols; col++){ 11 | b = image.at(row, col).val[0]; 12 | g = image.at(row, col).val[1]; 13 | r = image.at(row, col).val[2]; 14 | 15 | max = cv::max(b, cv::max(g, r)); 16 | min = cv::min(b, cv::min(g, r)); 17 | 18 | delta = (max - min) * 1.0 / 255; 19 | if(delta == 0) 20 | continue; 21 | value = (max + min) * 1.0 / 255; 22 | L = value / 2; 23 | if(L < 0.5) 24 | S = delta / value; 25 | else 26 | S = delta / (2 - value); 27 | 28 | if(increment + S >= 1) 29 | alpha = S; 30 | else 31 | alpha = 1 - increment; 32 | 33 | alpha = 1 / alpha - 1; 34 | 35 | image.at(row, col).val[0] = b + (b - L * 255) * alpha; 36 | image.at(row, col).val[1] = g + (g - L * 255) * alpha; 37 | image.at(row, col).val[2] = r + (r - L * 255) * alpha; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ImageWorkShop/Saturation.h: -------------------------------------------------------------------------------- 1 | #ifndef SATURATION_H 2 | #define SATURATION_H 3 | #include 4 | #include 5 | #include 6 | class Saturation{ 7 | public: 8 | void saturation(cv::Mat &model, double variable); 9 | private: 10 | }; 11 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/Vignette.cpp: -------------------------------------------------------------------------------- 1 | #include "Vignette.h" 2 | #include 3 | void Vignette::vignette(cv::Mat &img, double variable){ 4 | cv::Mat model(img.size(), CV_64F); 5 | generateModel(model, variable); 6 | 7 | cv::Mat labImg(img.size(), CV_8UC3); 8 | 9 | cv::cvtColor(img, labImg, CV_BGR2Lab); 10 | for (int row = 0; row < labImg.size().height; row++) 11 | { 12 | for (int col = 0; col < labImg.size().width; col++) 13 | { 14 | cv::Vec3b value = labImg.at(row, col); 15 | value.val[0] *= model.at(row, col); 16 | labImg.at(row, col) = value; 17 | } 18 | } 19 | cv::cvtColor(labImg, img, CV_Lab2BGR); 20 | } 21 | 22 | double Vignette::getDis(cv::Point &a, cv::Point &b){ 23 | return sqrt(pow((double) (a.x - b.x), 2) + pow((double) (a.y - b.y), 2)); 24 | } 25 | 26 | void Vignette::generateModel(cv::Mat &model, double variable){ 27 | cv::Point center = cv::Point(model.size().width/2, model.size().height/2); 28 | double longestDis = getLongestDis(center, model.size().height, model.size().width); 29 | for (int i = 0; i < model.rows; i++) 30 | { 31 | for (int j = 0; j < model.cols; j++) 32 | { 33 | double temp = getDis(center, cv::Point(j, i)) / (longestDis * variable); 34 | double temp_s = pow(cos(temp), 4); 35 | model.at(i, j) = temp_s; 36 | } 37 | } 38 | } 39 | 40 | double Vignette::getLongestDis(cv::Point& center, int height, int width){ 41 | std::vector point(4); 42 | point[0] = cv::Point(0,0); 43 | point[0] = cv::Point(0,height); 44 | point[0] = cv::Point(width,0); 45 | point[0] = cv::Point(width,height); 46 | double result = 0; 47 | for(int i = 0; i < 4; i++){ 48 | double d = getDis(point[i], center); 49 | if(d > result) 50 | result = d; 51 | } 52 | return result; 53 | } 54 | -------------------------------------------------------------------------------- /ImageWorkShop/Vignette.h: -------------------------------------------------------------------------------- 1 | #ifndef VIGNETTE_H 2 | #define VIGNETTE_H 3 | #include 4 | #include 5 | #include 6 | class Vignette{ 7 | public: 8 | void vignette(cv::Mat &model, double variable); 9 | private: 10 | double getDis(cv::Point &a, cv::Point &b); 11 | void generateModel(cv::Mat &model, double variable); 12 | double getLongestDis(cv::Point& center, int height, int width); 13 | 14 | }; 15 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/WhiteBalance.cpp: -------------------------------------------------------------------------------- 1 | #include "WhiteBalance.h" 2 | void WhiteBalance::perfectReflact(cv::Mat &image, int ratio){ 3 | int *record = new int[image.rows * image.cols]; 4 | for(int i = 0; i < image.rows * image.cols; i++) 5 | record[i] = 0; 6 | for(int row = 0; row < image.rows; row++){ 7 | for(int col = 0; col < image.cols; col++){ 8 | record[row * image.cols + col] = image.at(row, col).val[0] + image.at(row, col).val[1] + image.at(row, col).val[2]; 9 | } 10 | } 11 | 12 | int histogram[255 * 3 + 1]; 13 | for(int i = 0; i < 255 * 3; i++) 14 | histogram[i] = 0; 15 | for(int i = 0; i < image.rows * image.cols; i++) 16 | histogram[record[i]]++; 17 | int sum = 0; 18 | int threshold; 19 | for(int i = 255 * 3 - 1; i > 0; i--){ 20 | sum += histogram[i]; 21 | if(sum > image.rows * image.cols * ratio / 100){ 22 | threshold = i; 23 | break; 24 | } 25 | } 26 | double avgB = 0, avgG = 0, avgR = 0; 27 | int amount = 0; 28 | for(int row = 0; row < image.rows; row++){ 29 | for(int col = 0; col < image.cols; col++){ 30 | if(record[row * image.cols + col] > threshold){ 31 | avgB += image.at(row, col).val[0]; 32 | avgG += image.at(row, col).val[1]; 33 | avgR += image.at(row, col).val[2]; 34 | amount++; 35 | } 36 | } 37 | } 38 | 39 | avgB /= amount; 40 | avgG /= amount; 41 | avgR /= amount; 42 | 43 | int r, g, b; 44 | int max = 255; 45 | for(int row = 0; row < image.rows; row++){ 46 | for(int col = 0; col < image.cols; col++){ 47 | if(avgB > 0){ 48 | b = image.at(row, col).val[0]; 49 | b = b * max / avgB; 50 | if(b > 255) b = 255; 51 | else if(b < 0) 52 | b = 0; 53 | image.at(row, col).val[0] = b; 54 | } 55 | if(avgG > 0){ 56 | g = image.at(row, col).val[1]; 57 | g = g * max / avgG; 58 | if(g > 255) g = 255; 59 | else if(g < 0) 60 | g = 0; 61 | image.at(row, col).val[1] = g; 62 | } 63 | if(avgR > 0){ 64 | r = image.at(row, col).val[2]; 65 | r = r * max / avgR; 66 | if(r > 255) r = 255; 67 | else if(r < 0) 68 | r = 0; 69 | image.at(row, col).val[2] = r; 70 | } 71 | } 72 | } 73 | 74 | delete record; 75 | } -------------------------------------------------------------------------------- /ImageWorkShop/WhiteBalance.h: -------------------------------------------------------------------------------- 1 | #ifndef WHITEBALANCE_H 2 | #define WHITEBALANCE_H 3 | #include 4 | #include 5 | #include 6 | class WhiteBalance{ 7 | public: 8 | void perfectReflact(cv::Mat &image, int ratio); 9 | private: 10 | //double getDis(cv::Point &a, cv::Point &b); 11 | //void generateModel(cv::Mat &model, double variable); 12 | //double getLongestDis(cv::Point& center, int height, int width); 13 | 14 | }; 15 | #endif -------------------------------------------------------------------------------- /ImageWorkShop/imageworkshop.cpp: -------------------------------------------------------------------------------- 1 | #include "imageworkshop.h" 2 | #include 3 | #include 4 | #include 5 | 6 | ImageWorkShop::ImageWorkShop(QWidget *parent) 7 | : QMainWindow(parent) 8 | { 9 | ui.setupUi(this); 10 | 11 | brushSize = 1; 12 | skinMaskRadius = 5; 13 | whitenThreshold = 0; 14 | active = NONE; 15 | lomoMode = NOMODE; 16 | QString lomoStr[] = {"", "SEPIA", "PENCIL", "CARVING", "LOMO1"}; 17 | 18 | for(int i = 0; i < 5; i++) 19 | ui.comboBox_Lomo->addItem(lomoStr[i]); 20 | 21 | QString patchmatchifgpu[] = {"GPU_JF", "CPU"}; 22 | for(int i = 0; i < 2; i++) 23 | ui.comboBox_ifGpu->addItem(patchmatchifgpu[i]); 24 | initImageWorkShop(); 25 | 26 | ////opencl JumpFlooding test 27 | //QString filename; 28 | //filename = "C:\\Users\\qinghua\\Documents\\Visual Studio 2012\\Projects\\ImageWorkShop\\ImageWorkShop\\22222.jpg"; 29 | //std::string str = filename.toLocal8Bit(); 30 | //cvImage = cv::imread(str) ; 31 | //Mat temp; 32 | //cvImage.copyTo(temp); 33 | //filename = "C:\\Users\\qinghua\\Documents\\Visual Studio 2012\\Projects\\ImageWorkShop\\ImageWorkShop\\11111.jpg"; 34 | //str = filename.toLocal8Bit(); 35 | //cvImage = cv::imread(str) ; 36 | //myPatchMatch.imageInpaintCL_JF_TEST(temp, cvImage); 37 | } 38 | 39 | ImageWorkShop::~ImageWorkShop() 40 | { 41 | //if(qImage != NULL) 42 | // delete qImage; 43 | //if(qOriginImage != NULL) 44 | // delete qOriginImage; 45 | } 46 | 47 | void ImageWorkShop::initImageWorkShop(){ 48 | //imagewidget = new ImageWidget(ui.centralWidget); 49 | loadImage = false; 50 | connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(slotOpenFile())); 51 | connect(ui.actionSave_as, SIGNAL(triggered()), this, SLOT(slotSaveFile())); 52 | connect(ui.actionImage_last_saved, SIGNAL(triggered()), this, SLOT(slotCompare())); 53 | connect(ui.actionStageSave, SIGNAL(triggered()), this, SLOT(slotStageSave())); 54 | connect(ui.actionStageBack, SIGNAL(triggered()), this, SLOT(slotStageBack())); 55 | connect(ui.horizontalSliderVignette, SIGNAL(actionTriggered(int)), this, SLOT(slotVignetteFactor())); 56 | connect(ui.pushButtonMedian, SIGNAL(clicked()), this, SLOT(slotMedian())); 57 | connect(ui.horizontalSliderGauss, SIGNAL(actionTriggered(int)), this, SLOT(slotGauss())); 58 | connect(ui.horizontalSliderBalance, SIGNAL(actionTriggered(int)), this, SLOT(slotWhiteBalance())); 59 | connect(ui.horizontalSliderSaturation, SIGNAL(actionTriggered(int)), this, SLOT(slotSaturation())); 60 | 61 | connect(ui.pushButtonSharp, SIGNAL(clicked()), this, SLOT(slotSharp())); 62 | 63 | connect(ui.pushButtonLiquify, SIGNAL(clicked()), this, SLOT(slotLiquify())); 64 | connect(ui.pushButtonLiquifyRadius, SIGNAL(clicked()), this, SLOT(slotLiquifySetRadius())); 65 | 66 | connect(ui.comboBox_Lomo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotLomo())); 67 | connect(ui.horizontalSliderLomoR, SIGNAL(actionTriggered(int)), this, SLOT(slotLomoR())); 68 | connect(ui.horizontalSliderLomoG, SIGNAL(actionTriggered(int)), this, SLOT(slotLomoG())); 69 | connect(ui.horizontalSliderLomoB, SIGNAL(actionTriggered(int)), this, SLOT(slotLomoB())); 70 | 71 | connect(ui.pushButton_Exfoliating, SIGNAL(clicked()), this, SLOT(slotExfoliating())); 72 | 73 | connect(ui.horizontalSliderWhitenSkin, SIGNAL(actionTriggered(int)), this, SLOT(slotWhitenSkin())); 74 | 75 | connect(ui.horizontalSliderWhitenSkinMask, SIGNAL(actionTriggered(int)), this, SLOT(slotDrawSkinMaskRadius())); 76 | connect(ui.horizontalSliderThreshold, SIGNAL(actionTriggered(int)), this, SLOT(slotWhitenThreshold())); 77 | 78 | connect(ui.pushButton_Source, SIGNAL(clicked()), this, SLOT(slotColorMapSource())); 79 | connect(ui.pushButton_Target, SIGNAL(clicked()), this, SLOT(slotColorMapTarget())); 80 | connect(ui.pushButton_Result, SIGNAL(clicked()), this, SLOT(slotColorMapResult())); 81 | connect(ui.pushButton_ResultGrayToRGB, SIGNAL(clicked()), this, SLOT(slotColorMapGrayToRGB())); 82 | 83 | 84 | connect(ui.horizontalSliderBrushRadiusImageCopy, SIGNAL(actionTriggered(int)), this, SLOT(slotImageCopyRadius())); 85 | connect(ui.pushButtonMovePatch, SIGNAL(clicked()), this, SLOT(slotImageCopyMovePatch())); 86 | 87 | connect(ui.horizontalSliderBrushRadiusImageInpaintHole, SIGNAL(actionTriggered(int)), this, SLOT(slotImageInpaintRadius())); 88 | connect(ui.pushButtonImageInpaintHoleResult, SIGNAL(clicked()), this, SLOT(slotImageInpaintResult())); 89 | 90 | connect(ui.horizontalSliderBrushRadiusImageInpaintHoleRestrict, SIGNAL(actionTriggered(int)), this, SLOT(slotImageInpaintRestrictRadius())); 91 | connect(ui.pushButtonImageInpaintHoleRestrictResult, SIGNAL(clicked()), this, SLOT(slotImageInpaintRestrictResult())); 92 | connect(ui.pushButtonImageInpaintHoleRestrictResultOut, SIGNAL(clicked()), this, SLOT(slotImageInpaintRestrictResultOut())); 93 | connect(ui.pushButtonErodeRadius, SIGNAL(clicked()), this, SLOT(slotRrodeRadius())); 94 | connect(ui.comboBox_ifGpu, SIGNAL(currentIndexChanged(int)), this, SLOT(slotPatchMatchIfGpu())); 95 | 96 | connect(ui.pushButton_ClearRestrict, SIGNAL(clicked()), this, SLOT(slotClearRestrict())); 97 | connect(ui.pushButton_ClearRegion, SIGNAL(clicked()), this, SLOT(slotClearRegion())); 98 | 99 | } 100 | //void ImageWorkShop::initMenus(){ 101 | // 102 | //} 103 | 104 | void ImageWorkShop::slotOpenFile(){ 105 | QString filename; 106 | filename= QFileDialog::getOpenFileName(this, 107 | tr("open file"), "", 108 | tr("Images (*.png *.bmp *.jpeg *.jpg)")); 109 | //filename = "C:\\Users\\qinghua\\Documents\\Visual Studio 2012\\Projects\\ImageWorkShop\\ImageWorkShop\\6.png"; 110 | if(filename.isEmpty()) 111 | { 112 | return; 113 | } 114 | else { 115 | loadImage = true; 116 | 117 | loadtargetimage = false; 118 | std::string str = filename.toLocal8Bit(); 119 | cvImage = cv::imread(str) ; 120 | cvImage.copyTo(cvOriginImage); 121 | //qImage = MatToQimage(cvImage); 122 | 123 | QFileInfo fi = QFileInfo(filename); 124 | name = fi.fileName().toLocal8Bit(); 125 | name = "image"; 126 | cv::imshow(name, cvImage) ; 127 | 128 | //faceBeautification.bilateralFilter(cvImage, 3); 129 | //cv::imshow("12", cvImage) ; 130 | cv::setMouseCallback("image", onMouse, 0); 131 | cvOriginImage.copyTo(skinMask); 132 | zeroImage(skinMask); 133 | myPatchMatch.zeroImageCopyMask(cvImage.rows * cvImage.cols, true); 134 | myPatchMatch.zeroInpaintMask(cvImage.rows * cvImage.cols, true); 135 | //patchMatch.zeroMask(cvImage.rows * cvImage.cols, true); 136 | //faceBeautification.genFaceMask(cvImage); 137 | //loadfile(); 138 | //ui.labelImage->setPixmap(QPixmap::fromImage(*qImage)); 139 | ui.comboBox_Lomo->setCurrentIndex(0); 140 | } 141 | } 142 | 143 | void ImageWorkShop::slotSaveFile(){ 144 | QString fileName; 145 | QString slcStr; 146 | if(!loadImage){ 147 | QMessageBox::information(this, 148 | tr("you did not load any image"), 149 | tr("image save fail")); 150 | return; 151 | } 152 | fileName= QFileDialog::getSaveFileName(this, 153 | tr("save file"), "", 154 | tr("*.bmp;; *.png;; *.jpeg"), &slcStr); 155 | if(fileName.isEmpty()) 156 | { 157 | return; 158 | } 159 | else { 160 | if (QFileInfo(fileName).suffix().isEmpty()){ 161 | if(slcStr.right(3)=="bmp") 162 | { 163 | fileName+=".bmp"; 164 | } 165 | if(slcStr.right(3)=="png") 166 | { 167 | fileName+=".png"; 168 | } 169 | if(slcStr.right(4)=="jpeg") 170 | { 171 | fileName+=".jpeg"; 172 | } 173 | } 174 | std::string str = fileName.toLocal8Bit(); 175 | cv::imwrite(str, cvImage) ; 176 | 177 | } 178 | } 179 | QImage* ImageWorkShop::MatToQimage(cv::Mat &cvImage){ 180 | cv::Mat img; 181 | QImage *result; 182 | //switch(cvImage.depth()){ 183 | // case 184 | //} 185 | cvtColor(cvImage, img, CV_BGR2RGB); 186 | result = new QImage((unsigned char*)img.data, // uchar* data 187 | img.cols, img.rows, // width height 188 | // img.step, //bytesPerLine 189 | QImage::Format_RGB888); 190 | return result; 191 | } 192 | 193 | void ImageWorkShop::slotVignetteFactor(){ 194 | if(!loadImage){ 195 | return; 196 | } 197 | ui.comboBox_Lomo->setCurrentIndex(0); 198 | active = NONE; 199 | double factor = (ui.horizontalSliderVignette->value() + 6) * 1.0 / 10; 200 | cvOriginImage.copyTo(cvImage); 201 | vignette.vignette(cvImage, factor); 202 | 203 | QString s = QString::number(factor,'f',3); 204 | ui.lineEditVignette->setText(s); 205 | cv::imshow("image", cvImage); 206 | } 207 | void ImageWorkShop::slotMedian(){ 208 | if(!loadImage){ 209 | return; 210 | } 211 | active = NONE; 212 | ui.comboBox_Lomo->setCurrentIndex(0); 213 | int radius = ui.spinBoxMedian->value(); 214 | cvOriginImage.copyTo(cvImage); 215 | medianFilter.medianFilter(cvImage, radius); 216 | cv::imshow("image", cvImage); 217 | } 218 | void ImageWorkShop::slotStageSave(){ 219 | if(!loadImage){ 220 | return; 221 | } 222 | active = NONE; 223 | cvImage.copyTo(cvOriginImage); 224 | ui.comboBox_Lomo->setCurrentIndex(0); 225 | } 226 | void ImageWorkShop::slotStageBack(){ 227 | if(!loadImage){ 228 | return; 229 | } 230 | active = NONE; 231 | ui.comboBox_Lomo->setCurrentIndex(0); 232 | cvOriginImage.copyTo(cvImage); 233 | cv::imshow("image", cvOriginImage); 234 | } 235 | 236 | void ImageWorkShop::slotGauss(){ 237 | if(!loadImage){ 238 | return; 239 | } 240 | ui.comboBox_Lomo->setCurrentIndex(0); 241 | active = NONE; 242 | int radius = ui.horizontalSliderGauss->value(); 243 | cvOriginImage.copyTo(cvImage); 244 | gaussFilter.gaussFilter(cvImage, radius); 245 | 246 | QString s = QString::number(radius); 247 | ui.lineEditGauss->setText(s); 248 | cv::imshow("image", cvImage); 249 | } 250 | 251 | void ImageWorkShop::slotCompare(){ 252 | if(!loadImage){ 253 | return; 254 | } 255 | cv::imshow("origin image", cvOriginImage); 256 | } 257 | 258 | void ImageWorkShop::slotSharp(){ 259 | if(!loadImage){ 260 | return; 261 | } 262 | ui.comboBox_Lomo->setCurrentIndex(0); 263 | active = NONE; 264 | cvOriginImage.copyTo(cvImage); 265 | imageSharp.sharp(cvImage); 266 | cv::imshow("image", cvImage); 267 | } 268 | 269 | 270 | void ImageWorkShop::slotSaturation(){ 271 | if(!loadImage){ 272 | return; 273 | } 274 | ui.comboBox_Lomo->setCurrentIndex(0); 275 | active = NONE; 276 | int inc = ui.horizontalSliderSaturation->value() - 50; 277 | cvOriginImage.copyTo(cvImage); 278 | saturation.saturation(cvImage, inc * 1.0 / 100); 279 | 280 | QString s = QString::number(inc * 1.0 / 100,'f',2); 281 | ui.lineEditSaturation->setText(s); 282 | cv::imshow("image", cvImage); 283 | } 284 | 285 | void ImageWorkShop::slotImageCopyRadius(){ 286 | if(!loadImage){ 287 | return; 288 | } 289 | active = PATCHMATCH; 290 | myPatchMatch.interection = ImageCopy; 291 | myPatchMatch.ImageCopyMode = ADDTARGET; 292 | myPatchMatch.ImageCopyRadius = ui.horizontalSliderBrushRadiusImageCopy->value(); 293 | ui.lineEditBrushRadiusImageCopy->setText(QString::number(myPatchMatch.ImageCopyRadius)); 294 | } 295 | 296 | void ImageWorkShop::slotImageCopyMovePatch(){ 297 | if(!loadImage){ 298 | return; 299 | } 300 | myPatchMatch.ImageCopyMode = MOVE; 301 | active = PATCHMATCH; 302 | myPatchMatch.interection = ImageCopy; 303 | myPatchMatch.ImageCopyMode = MOVE; 304 | } 305 | 306 | 307 | void ImageWorkShop::slotImageInpaintRadius(){ 308 | if(!loadImage){ 309 | return; 310 | } 311 | active = PATCHMATCH; 312 | myPatchMatch.interection = INPAINT; 313 | myPatchMatch.ImageInpaintMode = INPAINT_HOLE; 314 | myPatchMatch.ImageInpaintRadius = ui.horizontalSliderBrushRadiusImageInpaintHole->value(); 315 | ui.lineEditBrushRadiusImageInpaintHole->setText(QString::number(myPatchMatch.ImageInpaintRadius)); 316 | } 317 | 318 | void ImageWorkShop::slotImageInpaintRestrictRadius(){ 319 | if(!loadImage){ 320 | return; 321 | } 322 | active = PATCHMATCH; 323 | myPatchMatch.interection = INPAINT; 324 | myPatchMatch.ImageInpaintMode = INPAINT_RESTRICT; 325 | myPatchMatch.ImageInpaintRestrictRadius = ui.horizontalSliderBrushRadiusImageInpaintHoleRestrict->value(); 326 | ui.lineEditBrushRadiusImageInpaintHoleRestrict->setText(QString::number(myPatchMatch.ImageInpaintRestrictRadius)); 327 | } 328 | 329 | void ImageWorkShop::slotImageInpaintResult(){ 330 | if(!loadImage){ 331 | return; 332 | } 333 | active = PATCHMATCH; 334 | myPatchMatch.interection = INPAINT; 335 | myPatchMatch.ImageInpaintMode = INPAINT_NO; 336 | myPatchMatch.ImageInpaintModeWhenWork = INPAINT_HOLE; 337 | cvOriginImage.copyTo(cvImage); 338 | 339 | //red 340 | for(int row = 0; row < cvImage.rows; row++){ 341 | for(int col = 0; col < cvImage.cols; col++){ 342 | if(cvImage.at(row, col)[2] > 230 && cvImage.at(row, col)[0] + cvImage.at(row, col)[1] < 20) 343 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 1; 344 | } 345 | } 346 | //black 347 | for(int row = 0; row < cvImage.rows; row++){ 348 | for(int col = 0; col < cvImage.cols; col++){ 349 | if(cvImage.at(row, col) == cv::Vec3b(0,0,0)) 350 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 1; 351 | } 352 | } 353 | 354 | myPatchMatch.erodeMask(cvImage.rows, cvImage.cols); 355 | 356 | for(int row = 0; row < cvImage.rows; row++){ 357 | for(int col = 0; col < cvImage.cols; col++){ 358 | if(myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] > 0){ 359 | cvImage.at(row, col).val[0] = 0; 360 | cvImage.at(row, col).val[1] = 0; 361 | cvImage.at(row, col).val[2] = 0; 362 | } 363 | } 364 | } 365 | 366 | //imshow("image",cvImage); 367 | //cvWaitKey(); 368 | cv::Mat temp; 369 | cvImage.copyTo(temp); 370 | switch(myPatchMatch.mode){ 371 | case CPU: 372 | myPatchMatch.imageInpaint(temp, cvImage); 373 | break; 374 | case GPU_JUMPFLOODING: 375 | myPatchMatch.imageInpaintCL_JF(temp, cvImage); 376 | break; 377 | } 378 | myPatchMatch.zeroInpaintMask(cvImage.rows * cvImage.cols, false); 379 | cv::imshow("image", cvImage); 380 | //waitKey(); 381 | 382 | myPatchMatch.ImageInpaintModeWhenWork = INPAINT_NO; 383 | } 384 | 385 | void ImageWorkShop::slotImageInpaintRestrictResult(){ 386 | if(!loadImage){ 387 | return; 388 | } 389 | active = PATCHMATCH; 390 | myPatchMatch.interection = INPAINT; 391 | myPatchMatch.ImageInpaintMode = INPAINT_NO; 392 | myPatchMatch.ImageInpaintModeWhenWork = INPAINT_RESTRICT; 393 | cvOriginImage.copyTo(cvImage); 394 | 395 | char* holeInRestrict = new char[cvImage.rows * cvImage.cols]; 396 | 397 | 398 | 399 | //get hole 400 | for(int row = 0; row < cvImage.rows; row++){ 401 | for(int col = 0; col < cvImage.cols; col++){ 402 | if(cvImage.at(row, col) == cv::Vec3b(0,0,0)) 403 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 1; 404 | } 405 | } 406 | for(int row = 0; row < cvImage.rows; row++){ 407 | for(int col = 0; col < cvImage.cols; col++){ 408 | if(cvImage.at(row, col)[2] > 230 && cvImage.at(row, col)[0] + cvImage.at(row, col)[1] < 20) 409 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 1; 410 | } 411 | } 412 | myPatchMatch.erodeMask(cvImage.rows, cvImage.cols); 413 | 414 | 415 | //only mark pixel "hole" when this pixel is a hole and is in restrict, then remove the restrict mark on the pixel 416 | // and removel the hole attrib of the pixel in ImageInpaintMask 417 | for(int row = 0; row < cvImage.rows; row++){ 418 | for(int col = 0; col < cvImage.cols; col++){ 419 | if(myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] == 1 && myPatchMatch.InpaintRestrictMask[row * cvImage.cols + col] == 1){ 420 | holeInRestrict[row * cvImage.cols + col] = 1; 421 | myPatchMatch.InpaintRestrictMask[row * cvImage.cols + col] = 0; 422 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 0; 423 | } 424 | else{ 425 | holeInRestrict[row * cvImage.cols + col] = 0; 426 | } 427 | } 428 | } 429 | 430 | for(int row = 0; row < cvImage.rows; row++){ 431 | for(int col = 0; col < cvImage.cols; col++){ 432 | if(myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] > 0){ 433 | cvImage.at(row, col).val[0] = 0; 434 | cvImage.at(row, col).val[1] = 0; 435 | cvImage.at(row, col).val[2] = 0; 436 | } 437 | } 438 | } 439 | 440 | cv::Mat temp; 441 | cvImage.copyTo(temp); 442 | 443 | 444 | //myPatchMatch.imageInpaintWithRestrict(temp, cvImage, holeInRestrict); 445 | switch(myPatchMatch.mode){ 446 | case CPU: 447 | myPatchMatch.imageInpaintWithRestrict(temp, cvImage, holeInRestrict); 448 | break; 449 | case GPU_JUMPFLOODING: 450 | myPatchMatch.imageInpaintWithRestrictCL_JF(temp, cvImage, holeInRestrict); 451 | break; 452 | } 453 | 454 | //zero InpaintRestrictMask 455 | for(int row = 0; row < cvImage.rows; row++){ 456 | for(int col = 0; col < cvImage.cols; col++){ 457 | myPatchMatch.InpaintRestrictMask[row * cvImage.cols + col] = 0; 458 | } 459 | } 460 | //free memory of holeInRestrict 461 | delete holeInRestrict; 462 | 463 | myPatchMatch.ImageInpaintModeWhenWork = INPAINT_NO; 464 | } 465 | 466 | void ImageWorkShop::slotImageInpaintRestrictResultOut(){ 467 | if(!loadImage){ 468 | return; 469 | } 470 | active = PATCHMATCH; 471 | myPatchMatch.interection = INPAINT; 472 | myPatchMatch.ImageInpaintMode = INPAINT_NO; 473 | myPatchMatch.ImageInpaintModeWhenWork = INPAINT_RESTRICT; 474 | cvOriginImage.copyTo(cvImage); 475 | 476 | char* holeInRestrict = new char[cvImage.rows * cvImage.cols]; 477 | 478 | 479 | 480 | //get hole 481 | for(int row = 0; row < cvImage.rows; row++){ 482 | for(int col = 0; col < cvImage.cols; col++){ 483 | if(cvImage.at(row, col) == cv::Vec3b(0,0,0)) 484 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 1; 485 | } 486 | } 487 | for(int row = 0; row < cvImage.rows; row++){ 488 | for(int col = 0; col < cvImage.cols; col++){ 489 | if(cvImage.at(row, col)[2] > 230 && cvImage.at(row, col)[0] + cvImage.at(row, col)[1] < 20) 490 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 1; 491 | } 492 | } 493 | myPatchMatch.erodeMask(cvImage.rows, cvImage.cols); 494 | 495 | 496 | //only mark pixel "hole" when this pixel is a hole and is in restrict, then remove the restrict mark on the pixel 497 | // and removel the hole attrib of the pixel in ImageInpaintMask 498 | for(int row = 0; row < cvImage.rows; row++){ 499 | for(int col = 0; col < cvImage.cols; col++){ 500 | if(myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] == 1){ 501 | holeInRestrict[row * cvImage.cols + col] = 1; 502 | myPatchMatch.InpaintRestrictMask[row * cvImage.cols + col] = 0; 503 | myPatchMatch.ImageInpaintMask[row * cvImage.cols + col] = 0; 504 | } 505 | 506 | } 507 | } 508 | 509 | 510 | cv::Mat temp; 511 | cvImage.copyTo(temp); 512 | switch(myPatchMatch.mode){ 513 | case CPU: 514 | myPatchMatch.imageInpaintWithRestrict(temp, cvImage, holeInRestrict); 515 | break; 516 | case GPU_JUMPFLOODING: 517 | myPatchMatch.imageInpaintWithRestrictCL_JF(temp, cvImage, holeInRestrict); 518 | break; 519 | } 520 | myPatchMatch.zeroInpaintMask(cvImage.rows * cvImage.cols, false); 521 | 522 | 523 | //zero InpaintRestrictMask 524 | for(int row = 0; row < cvImage.rows; row++){ 525 | for(int col = 0; col < cvImage.cols; col++){ 526 | myPatchMatch.InpaintRestrictMask[row * cvImage.cols + col] = 0; 527 | } 528 | } 529 | //free memory of holeInRestrict 530 | delete holeInRestrict; 531 | 532 | myPatchMatch.ImageInpaintModeWhenWork = INPAINT_NO; 533 | } 534 | void ImageWorkShop::slotRrodeRadius(){ 535 | if(!loadImage){ 536 | return; 537 | } 538 | myPatchMatch.erodeRadius = ui.spinBoxErodeRadius->value(); 539 | } 540 | void ImageWorkShop::slotWhiteBalance(){ 541 | if(!loadImage){ 542 | return; 543 | } 544 | ui.comboBox_Lomo->setCurrentIndex(0); 545 | active = NONE; 546 | int ratio = ui.horizontalSliderBalance->value(); 547 | cvOriginImage.copyTo(cvImage); 548 | whiteBalance.perfectReflact(cvImage, ratio); 549 | QString s = QString::number(ratio); 550 | ui.lineEditBalance->setText(s); 551 | cv::imshow("image", cvImage); 552 | } 553 | 554 | void ImageWorkShop::slotLiquifySetRadius(){ 555 | if(active != LIQUIFY) 556 | return; 557 | ui.comboBox_Lomo->setCurrentIndex(0); 558 | int radius = ui.spinBoxLiquifyRadius->value(); 559 | liquify.radius = radius; 560 | liquify.genMask(); 561 | } 562 | 563 | void ImageWorkShop::slotLiquify(){ 564 | if(!loadImage){ 565 | return; 566 | } 567 | ui.comboBox_Lomo->setCurrentIndex(0); 568 | active = LIQUIFY; 569 | cvOriginImage.copyTo(cvImage); 570 | liquify.image.rows = cvImage.rows; 571 | liquify.image.cols = cvImage.cols; 572 | liquify.image.dims = cvImage.dims; 573 | cv::imshow("image", cvImage); 574 | } 575 | 576 | void ImageWorkShop::slotLomo(){ 577 | if(!loadImage){ 578 | return; 579 | } 580 | active = NONE; 581 | int mode = ui.comboBox_Lomo->currentIndex(); 582 | cvOriginImage.copyTo(cvImage); 583 | switch(mode){ 584 | //case NOMODE: 585 | // break; 586 | case SEPIA: 587 | //lomo.Sepia(cvImage); 588 | lomo.Sepia2(cvImage); 589 | break; 590 | case PENCIL: 591 | lomo.Pencil(cvImage); 592 | break; 593 | case CARVING: 594 | lomo.Carving(cvImage); 595 | break; 596 | case LOMO1: 597 | lomo.lomoStyle1(cvImage); 598 | vignette.vignette(cvImage, 1.1); 599 | break; 600 | default: 601 | break; 602 | } 603 | cv::imshow("image", cvImage); 604 | } 605 | 606 | void ImageWorkShop::slotLomoR(){ 607 | if(!loadImage){ 608 | return; 609 | } 610 | active = NONE; 611 | cvOriginImage.copyTo(cvImage); 612 | int midR = ui.horizontalSliderLomoR->value(); 613 | int midG = ui.horizontalSliderLomoG->value(); 614 | int midB = ui.horizontalSliderLomoB->value(); 615 | unsigned char TB[256]; 616 | unsigned char TG[256]; 617 | unsigned char TR[256]; 618 | lomo.GetLevelTable(TR, 0, midR, 255, 0, 255); 619 | lomo.GetLevelTable(TG, 0, midG, 255, 0, 255); 620 | lomo.GetLevelTable(TB, 0, midB, 255, 0, 255); 621 | lomo.Curve(cvImage, TB, TG, TR); 622 | QString s = QString::number(midR); 623 | ui.lineEditLomoR->setText(s); 624 | cv::imshow("image", cvImage); 625 | } 626 | void ImageWorkShop::slotLomoG(){ 627 | if(!loadImage){ 628 | return; 629 | } 630 | active = NONE; 631 | cvOriginImage.copyTo(cvImage); 632 | int midR = ui.horizontalSliderLomoR->value(); 633 | int midG = ui.horizontalSliderLomoG->value(); 634 | int midB = ui.horizontalSliderLomoB->value(); 635 | unsigned char TB[256]; 636 | unsigned char TG[256]; 637 | unsigned char TR[256]; 638 | lomo.GetLevelTable(TR, 0, midR, 255, 0, 255); 639 | lomo.GetLevelTable(TG, 0, midG, 255, 0, 255); 640 | lomo.GetLevelTable(TB, 0, midB, 255, 0, 255); 641 | lomo.Curve(cvImage, TB, TG, TR); 642 | QString s = QString::number(midG); 643 | ui.lineEditLomoG->setText(s); 644 | cv::imshow("image", cvImage); 645 | } 646 | void ImageWorkShop::slotLomoB(){ 647 | if(!loadImage){ 648 | return; 649 | } 650 | active = NONE; 651 | cvOriginImage.copyTo(cvImage); 652 | int midR = ui.horizontalSliderLomoR->value(); 653 | int midG = ui.horizontalSliderLomoG->value(); 654 | int midB = ui.horizontalSliderLomoB->value(); 655 | unsigned char TB[256]; 656 | unsigned char TG[256]; 657 | unsigned char TR[256]; 658 | lomo.GetLevelTable(TR, 0, midR, 255, 0, 255); 659 | lomo.GetLevelTable(TG, 0, midG, 255, 0, 255); 660 | lomo.GetLevelTable(TB, 0, midB, 255, 0, 255); 661 | lomo.Curve(cvImage, TB, TG, TR); 662 | QString s = QString::number(midB); 663 | ui.lineEditLomoB->setText(s); 664 | cv::imshow("image", cvImage); 665 | } 666 | 667 | void ImageWorkShop::slotExfoliating(){ 668 | if(!loadImage){ 669 | return; 670 | } 671 | active = NONE; 672 | cvOriginImage.copyTo(cvImage); 673 | 674 | cv::Mat image(cvImage.size(), CV_64F); 675 | cvImage.copyTo(image); 676 | 677 | int vdev = ui.spinBox_Vdev->value(); 678 | int sdev = ui.spinBox_Sdev->value(); 679 | faceBeautification.bilateralFilter(image, vdev, 1.0 / sdev); 680 | //faceBeautification.genFaceMask(cvImage); 681 | 682 | cv::Mat GaussMask(skinMask.size(), CV_64F); 683 | skinMask.copyTo(GaussMask); 684 | int thre = ui.horizontalSliderThreshold->value(); 685 | gaussFilter.gaussFilter(GaussMask, thre); 686 | 687 | //cv::imshow("gaussMask", GaussMask); 688 | 689 | int k; 690 | for(int row = 0; row < cvImage.rows; row++){ 691 | for(int col = 0; col < cvImage.cols; col++){ 692 | //if(skinMask.at(row, col).val[0] == 255) 693 | // cvImage.at(row, col) = image.at(row, col); 694 | int gauss = GaussMask.at(row, col).val[0]; 695 | if(gauss > 0){ 696 | k = (cvImage.at(row, col).val[0] * 158 + 697 | cvImage.at(row, col).val[1] * 75 + 698 | cvImage.at(row, col).val[2] * 55) / (158 + 72 + 55); 699 | if(k > whitenThreshold){ 700 | int r, g, b; 701 | b = image.at(row, col).val[0] * gauss + cvImage.at(row, col).val[0] * (255 - gauss); 702 | g = image.at(row, col).val[1] * gauss + cvImage.at(row, col).val[1] * (255 - gauss); 703 | r = image.at(row, col).val[2] * gauss + cvImage.at(row, col).val[2] * (255 - gauss); 704 | 705 | cvImage.at(row, col).val[0] = b / 255; 706 | cvImage.at(row, col).val[1] = g / 255; 707 | cvImage.at(row, col).val[2] = r / 255; 708 | } 709 | //cvImage.at(row, col) = (image.at(row, col) * g + cvImage.at(row, col) * (255 - g); 710 | } 711 | } 712 | } 713 | cv::imshow("image", cvImage); 714 | } 715 | 716 | void ImageWorkShop::slotWhitenSkin(){ 717 | if(!loadImage){ 718 | return; 719 | } 720 | active = NONE; 721 | cvOriginImage.copyTo(cvImage); 722 | int beta = ui.horizontalSliderWhitenSkin->value(); 723 | 724 | cv::Mat image(cvImage.size(), CV_64F); 725 | cvImage.copyTo(image); 726 | 727 | faceBeautification.curve(image, beta); 728 | QString s = QString::number(beta); 729 | ui.lineEditWhitenSkin->setText(s); 730 | 731 | 732 | cv::Mat GaussMask(skinMask.size(), CV_64F); 733 | skinMask.copyTo(GaussMask); 734 | int thre = ui.horizontalSliderThreshold->value(); 735 | gaussFilter.gaussFilter(GaussMask, thre); 736 | 737 | //cv::imshow("gaussMask", GaussMask); 738 | 739 | int k; 740 | for(int row = 0; row < cvImage.rows; row++){ 741 | for(int col = 0; col < cvImage.cols; col++){ 742 | int gauss = GaussMask.at(row, col).val[0]; 743 | if(gauss > 0){ 744 | k = (cvImage.at(row, col).val[0] * 158 + 745 | cvImage.at(row, col).val[1] * 75 + 746 | cvImage.at(row, col).val[2] * 55) / (158 + 72 + 55); 747 | if(k > whitenThreshold){ 748 | int r, g, b; 749 | b = image.at(row, col).val[0] * gauss + cvImage.at(row, col).val[0] * (255 - gauss); 750 | g = image.at(row, col).val[1] * gauss + cvImage.at(row, col).val[1] * (255 - gauss); 751 | r = image.at(row, col).val[2] * gauss + cvImage.at(row, col).val[2] * (255 - gauss); 752 | 753 | cvImage.at(row, col).val[0] = b / 255; 754 | cvImage.at(row, col).val[1] = g / 255; 755 | cvImage.at(row, col).val[2] = r / 255; 756 | } 757 | //cvImage.at(row, col) = (image.at(row, col) * g + cvImage.at(row, col) * (255 - g); 758 | } 759 | } 760 | } 761 | cv::imshow("image", cvImage); 762 | } 763 | 764 | //void ImageWorkShop::slotDrawSkinMask(){ 765 | // if(!loadImage){ 766 | // return; 767 | // } 768 | // active = SKINMASK; 769 | //} 770 | void ImageWorkShop::slotDrawSkinMaskRadius(){ 771 | if(!loadImage){ 772 | return; 773 | } 774 | active = SKINMASK; 775 | //cvOriginImage.copyTo(cvImage); 776 | int radius = ui.horizontalSliderWhitenSkinMask->value(); 777 | skinMaskRadius = radius; 778 | //faceBeautification.curve(cvImage, beta); 779 | QString s = QString::number(radius); 780 | ui.lineEditWhitenSkinMask->setText(s); 781 | //cv::imshow("image", cvImage); 782 | } 783 | 784 | void ImageWorkShop::slotWhitenThreshold(){ 785 | if(!loadImage){ 786 | return; 787 | } 788 | active = SKINMASK; 789 | int thre = ui.horizontalSliderThreshold->value(); 790 | whitenThreshold = thre; 791 | 792 | QString s = QString::number(thre); 793 | ui.lineEditWhitenThreshold->setText(s); 794 | cv::imshow("image", cvImage); 795 | } 796 | 797 | void ImageWorkShop::slotColorMapSource(){ 798 | QString filename; 799 | filename= QFileDialog::getOpenFileName(this, 800 | tr("open color map source"), "", 801 | tr("Images (*.png *.bmp *.jpeg *.jpg)")); 802 | if(filename.isEmpty()) 803 | { 804 | return; 805 | } 806 | else { 807 | std::string str = filename.toLocal8Bit(); 808 | colorMapSource = cv::imread(str) ; 809 | 810 | cv::imshow("color map source", colorMapSource) ; 811 | } 812 | } 813 | 814 | void ImageWorkShop::slotColorMapTarget(){ 815 | QString filename; 816 | filename= QFileDialog::getOpenFileName(this, 817 | tr("open color map target"), "", 818 | tr("Images (*.png *.bmp *.jpeg *.jpg)")); 819 | if(filename.isEmpty()) 820 | { 821 | return; 822 | } 823 | else { 824 | std::string str = filename.toLocal8Bit(); 825 | colorMapTarget = cv::imread(str) ; 826 | 827 | cv::imshow("color map target", colorMapTarget) ; 828 | } 829 | } 830 | 831 | void ImageWorkShop::slotColorMapResult(){ 832 | if(colorMapSource.rows == 0 || colorMapTarget.rows == 0) 833 | return; 834 | ColorTransfer clt(colorMapSource, colorMapTarget); 835 | cv::imshow("color map result", clt.result) ; 836 | 837 | } 838 | void ImageWorkShop::slotColorMapGrayToRGB(){ 839 | if(colorMapSource.rows == 0 || colorMapTarget.rows == 0) 840 | return; 841 | ColorTransfer clt; 842 | clt.localVarianceTransfer(colorMapSource, colorMapTarget); 843 | } 844 | 845 | void ImageWorkShop::addToSkinMask(int ax, int ay){ 846 | int radius = skinMaskRadius; 847 | int centerX = ax; 848 | int centerY = ay; 849 | for(int row = -radius; row < radius + 1; row++){ 850 | for(int col = -radius; col < radius + 1; col++){ 851 | if(centerX + col < 0 || centerY + row < 0 || centerX + col >= skinMask.cols || centerY + row >= skinMask.rows) 852 | continue; 853 | if(row * row + col * col < radius * radius){ 854 | skinMask.at(centerY + row, centerX + col).val[0] = 255; 855 | skinMask.at(centerY + row, centerX + col).val[1] = 255; 856 | skinMask.at(centerY + row, centerX + col).val[2] = 255; 857 | } 858 | } 859 | } 860 | //cv::imshow("SkinMask", skinMask); 861 | } 862 | 863 | void ImageWorkShop::addMaskToImage(cv::Mat &img){ 864 | for(int row = 0; row < img.rows; row++){ 865 | for(int col = 0; col < img.cols; col++){ 866 | if(skinMask.at(row, col).val[0] == 255){ 867 | img.at(row, col).val[2] = (img.at(row, col).val[2] + 255) / 2; 868 | } 869 | } 870 | } 871 | } 872 | 873 | void ImageWorkShop::addCircle(cv::Mat &image, int ax, int ay){ 874 | int radius = skinMaskRadius; 875 | int centerX = ax; 876 | int centerY = ay; 877 | for(int row = -radius; row < radius + 1; row++){ 878 | for(int col = -radius; col < radius + 1; col++){ 879 | if(centerX + col < 0 || centerY + row < 0 || centerX + col >= image.cols || centerY + row >= image.rows) 880 | continue; 881 | if(row * row + col * col < radius * radius){ 882 | image.at(centerY + row, centerX + col).val[0] = 0; 883 | image.at(centerY + row, centerX + col).val[1] = 0; 884 | image.at(centerY + row, centerX + col).val[2] = 150; 885 | } 886 | } 887 | } 888 | } 889 | void ImageWorkShop::zeroImage(cv::Mat &img){ 890 | for(int row = 0; row < img.rows; row++){ 891 | for(int col = 0; col < img.cols; col++){ 892 | img.at(row, col).val[0] = 0; 893 | img.at(row, col).val[1] = 0; 894 | img.at(row, col).val[2] = 0; 895 | } 896 | } 897 | } 898 | 899 | 900 | void ImageWorkShop::slotPatchMatchIfGpu(){ 901 | active = NONE; 902 | myPatchMatch.mode = (PatchMatchMode)ui.comboBox_ifGpu->currentIndex(); 903 | } 904 | 905 | void ImageWorkShop::slotClearRestrict(){ 906 | if(!loadImage){ 907 | return; 908 | } 909 | active = NONE; 910 | int length = cvImage.rows * cvImage.cols; 911 | for(int i = 0; i < length; i++){ 912 | myPatchMatch.InpaintRestrictMask[i] = 0; 913 | } 914 | Mat temp = cvImage.clone(); 915 | myPatchMatch.showImageInpaintMaskImage(temp); 916 | imshow("image", temp); 917 | } 918 | void ImageWorkShop::slotClearRegion(){ 919 | if(!loadImage){ 920 | return; 921 | } 922 | active = NONE; 923 | myPatchMatch.zeroImageCopyMask(cvImage.rows * cvImage.cols, false); 924 | 925 | Mat temp = cvImage.clone(); 926 | myPatchMatch.showImageCopyMaskImage(temp); 927 | imshow("image", temp); 928 | } 929 | ImageWorkShop *imageworkshop; 930 | bool mouseDown = false;; 931 | void onMouse(int event,int ax,int ay,int flags,void* param ) 932 | { 933 | bool maskImageCopyToCvImage = false; 934 | cv::Mat img_circle; 935 | cv::Mat maskImage; 936 | //cv::imshow("asd", imageworkshop->cvImage); 937 | //waitKey(33); 938 | imageworkshop->cvImage.copyTo(maskImage); 939 | switch (event){ 940 | case CV_EVENT_MOUSEMOVE: 941 | if(mouseDown){ 942 | switch(imageworkshop->active){ 943 | case NONE: 944 | break; 945 | case LIQUIFY: 946 | imageworkshop->cvImage.copyTo(imageworkshop->liquify.image); 947 | imageworkshop->liquify.liquify(imageworkshop->liquify.image, 0, ax, ay); 948 | imageworkshop->liquify.addCircle(img_circle); 949 | cv::imshow("image", img_circle); 950 | break; 951 | case SKINMASK: 952 | imageworkshop->addToSkinMask(ax, ay); 953 | break; 954 | case PATCHMATCH: 955 | switch(imageworkshop->myPatchMatch.interection){ 956 | case ImageCopy: 957 | imageworkshop->myPatchMatch.dealWithImageCopyMouseMoveEvent(ax, ay, maskImage); 958 | break; 959 | case INPAINT: 960 | imageworkshop->myPatchMatch.dealWithImageInpaintMouseMoveEvent(ax, ay, maskImage); 961 | break; 962 | } 963 | break; 964 | } 965 | } 966 | break; 967 | case CV_EVENT_LBUTTONDOWN: 968 | switch(imageworkshop->active){ 969 | case NONE: 970 | break; 971 | case LIQUIFY: 972 | imageworkshop->liquify.centerX = ax; 973 | imageworkshop->liquify.centerY = ay; 974 | imageworkshop->cvImage.copyTo(imageworkshop->liquify.image); 975 | break; 976 | case SKINMASK: 977 | imageworkshop->addToSkinMask(ax, ay); 978 | break; 979 | case PATCHMATCH: 980 | switch(imageworkshop->myPatchMatch.interection){ 981 | case ImageCopy: 982 | imageworkshop->myPatchMatch.dealWithImageCopyMouseMoveButtonDown(ax, ay, maskImage); 983 | break; 984 | case INPAINT: 985 | imageworkshop->myPatchMatch.dealWithImageInpaintMouseButtonDown(ax, ay, maskImage); 986 | break; 987 | } 988 | break; 989 | } 990 | mouseDown = true; 991 | break; 992 | case CV_EVENT_LBUTTONUP: 993 | if(mouseDown){ 994 | switch(imageworkshop->active){ 995 | case NONE: 996 | break; 997 | case LIQUIFY: 998 | imageworkshop->liquify.image.copyTo(imageworkshop->cvImage); 999 | cv::imshow("image", imageworkshop->cvImage); 1000 | break; 1001 | case PATCHMATCH: 1002 | switch(imageworkshop->myPatchMatch.interection){ 1003 | case ImageCopy: 1004 | if(imageworkshop->myPatchMatch.dealWithImageCopyMouseMoveButtonUp(ax, ay, maskImage)){ 1005 | imageworkshop->myPatchMatch.interection = NO; 1006 | maskImageCopyToCvImage = true; 1007 | maskImage.copyTo(imageworkshop->cvImage); 1008 | } 1009 | break; 1010 | case INPAINT: 1011 | imageworkshop->myPatchMatch.dealWithImageInpaintMouseButtonUp(ax, ay, maskImage); 1012 | break; 1013 | } 1014 | break; 1015 | } 1016 | 1017 | } 1018 | mouseDown = false; 1019 | break; 1020 | } 1021 | 1022 | if(imageworkshop->active == SKINMASK){ 1023 | imageworkshop->addMaskToImage(maskImage); 1024 | imageworkshop->addCircle(maskImage, ax, ay); 1025 | cv::imshow("image", maskImage); 1026 | } 1027 | 1028 | if(imageworkshop->active == PATCHMATCH){ 1029 | if(imageworkshop->myPatchMatch.interection == ImageCopy){ 1030 | imageworkshop->myPatchMatch.showImageCopyMaskImage(maskImage); 1031 | if(imageworkshop->myPatchMatch.ImageCopyMode == ADDTARGET){ 1032 | imageworkshop->myPatchMatch.addCircleToImage(maskImage, ax, ay); 1033 | cv::imshow("image", maskImage); 1034 | } 1035 | if(imageworkshop->myPatchMatch.ImageCopyMode == MOVE){ 1036 | if(!imageworkshop->myPatchMatch.ImageCopyMoveStart) 1037 | cv::imshow("image", maskImage); 1038 | } 1039 | } 1040 | 1041 | if(imageworkshop->myPatchMatch.interection == INPAINT){ 1042 | if(imageworkshop->myPatchMatch.ImageInpaintMode != INPAINT_NO){ 1043 | imageworkshop->myPatchMatch.showImageInpaintMaskImage(maskImage); 1044 | imageworkshop->myPatchMatch.showImageInpaintRestrictMaskImage(maskImage); 1045 | imageworkshop->myPatchMatch.addCircleToImageInpaint(maskImage, ax, ay); 1046 | cv::imshow("image", maskImage); 1047 | } 1048 | } 1049 | } 1050 | } 1051 | 1052 | -------------------------------------------------------------------------------- /ImageWorkShop/imageworkshop.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEWORKSHOP_H 2 | #define IMAGEWORKSHOP_H 3 | 4 | #include 5 | #include "ui_imageworkshop.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "Vignette.h" 11 | #include "GaussFilter.h" 12 | #include "MedianFilter.h" 13 | #include "ImageSharpening.h" 14 | //#include "PatchMatch.h" 15 | #include "WhiteBalance.h" 16 | #include "Saturation.h" 17 | #include "Liquify.h" 18 | #include "Lomo.h" 19 | #include "FaceBeautification.h" 20 | #include "ColorTransfer.h" 21 | #include "MyPatchMatch.h" 22 | //#include "ImageWidget.h" 23 | enum LomoMode{NOMODE, SEPIA, PENCIL, CARVING, LOMO1}; 24 | enum Active{NONE, LIQUIFY, PATCHMATCH, LOMO, SKINMASK}; 25 | class ImageWorkShop : public QMainWindow 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | ImageWorkShop(QWidget *parent = 0); 31 | ~ImageWorkShop(); 32 | //void initMenus(); 33 | QImage *qImage; 34 | QImage *qOriginImage; 35 | cv::Mat cvImage; 36 | cv::Mat cvOriginImage; 37 | Vignette vignette; 38 | MedianFilter medianFilter; 39 | GaussFilter gaussFilter; 40 | ImageSharp imageSharp; 41 | //PatchMatch patchMatch; 42 | MyPatchMatch myPatchMatch; 43 | WhiteBalance whiteBalance; 44 | Saturation saturation; 45 | Liquify liquify; 46 | Lomo lomo; 47 | FaceBeautification faceBeautification; 48 | //ColorTransfer colorTransfer; 49 | 50 | //BITMAP *ann; 51 | cv::Mat target; 52 | int brushSize; 53 | int skinMaskRadius; 54 | int whitenThreshold; 55 | cv::Mat skinMask; 56 | Active active; 57 | LomoMode lomoMode; 58 | void addToSkinMask(int ax, int ay); 59 | void addCircle(cv::Mat &img, int ax, int ay); 60 | void addMaskToImage(cv::Mat &img); 61 | 62 | cv::Mat colorMapSource; 63 | cv::Mat colorMapTarget; 64 | private: 65 | //ImageWidget *imagewidget; 66 | bool loadImage; 67 | bool loadtargetimage; 68 | std::string name; 69 | Ui::ImageWorkShopClass ui; 70 | void initImageWorkShop(); 71 | void zeroImage(cv::Mat &img); 72 | QImage* MatToQimage(cv::Mat &cvImage); 73 | 74 | friend void onMouse(int event,int x,int y,int flags,void* param); 75 | public slots: 76 | void slotOpenFile(); 77 | void slotSaveFile(); 78 | void slotStageSave(); 79 | void slotStageBack(); 80 | void slotVignetteFactor(); 81 | void slotMedian(); 82 | void slotGauss(); 83 | void slotCompare(); 84 | void slotSharp(); 85 | void slotWhiteBalance(); 86 | 87 | //void slotTargetImage(); 88 | //void slotBrushRadius(); 89 | void slotSaturation(); 90 | 91 | void slotLiquifySetRadius(); 92 | void slotLiquify(); 93 | void slotLomo(); 94 | void slotLomoR(); 95 | void slotLomoG(); 96 | void slotLomoB(); 97 | void slotExfoliating(); 98 | void slotWhitenSkin(); 99 | //void slotDrawSkinMask(); 100 | void slotDrawSkinMaskRadius(); 101 | void slotWhitenThreshold(); 102 | 103 | void slotColorMapSource(); 104 | void slotColorMapTarget(); 105 | void slotColorMapResult(); 106 | void slotColorMapGrayToRGB(); 107 | 108 | void slotImageCopyRadius(); 109 | void slotImageCopyMovePatch(); 110 | 111 | void slotImageInpaintRadius(); 112 | void slotImageInpaintRestrictRadius(); 113 | void slotImageInpaintResult(); 114 | void slotImageInpaintRestrictResult(); 115 | void slotImageInpaintRestrictResultOut(); 116 | void slotRrodeRadius(); 117 | 118 | void slotPatchMatchIfGpu(); 119 | 120 | void slotClearRestrict(); 121 | void slotClearRegion(); 122 | 123 | }; 124 | 125 | 126 | #endif // IMAGEWORKSHOP_H 127 | -------------------------------------------------------------------------------- /ImageWorkShop/imageworkshop.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ImageWorkShop/main.cpp: -------------------------------------------------------------------------------- 1 | #include "imageworkshop.h" 2 | #include 3 | extern ImageWorkShop *imageworkshop; 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | ImageWorkShop w; 8 | imageworkshop = &w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /ImageWorkShop/openclShader/jumpFlooding.cl: -------------------------------------------------------------------------------- 1 | ushort computeDistance( __global const uchar* target, int target_row, int target_col, __global const uchar* source, 2 | int source_row, int source_col, const uint4 imageSize, __global const uchar* mask){ 3 | long distance = 0; 4 | long weight_sum = 0; 5 | int penalty = 655350; 6 | int radius = 2; 7 | for(int dy =- radius; dy <= radius; dy++) { 8 | for(int dx =- radius; dx <= radius; dx++) { 9 | weight_sum += penalty; 10 | 11 | int s_row = source_row + dy; 12 | int s_col = source_col + dx; 13 | if (s_row < 0 || s_row >= imageSize.x){ 14 | distance += penalty; 15 | continue; 16 | } 17 | 18 | if (s_col < 0 || s_col >= imageSize.y){ 19 | distance += penalty; 20 | continue; 21 | } 22 | 23 | //penalty for hole in source 24 | if (mask[s_row * imageSize.y + s_col] != 0) { 25 | distance += penalty; 26 | continue; 27 | } 28 | 29 | int t_row= target_row + dy; 30 | int t_col = target_col + dx; 31 | if (t_row < 0 || t_row >= imageSize.x){ 32 | distance += penalty; 33 | continue; 34 | } 35 | if (t_col < 0 || t_col >= imageSize.y){ 36 | distance += penalty; 37 | continue; 38 | } 39 | 40 | 41 | //compute ssd 42 | long ssd = 0; 43 | int weight[3] = {1, 6, 3}; 44 | for(int channel = 0; channel < 3; channel++){ 45 | int s = source[s_row * imageSize.y * 3 + s_col * 3 + channel]; 46 | int t = target[t_row * imageSize.y * 3 + t_col * 3 + channel]; 47 | float dis = (s - t) * (s - t); // Value 48 | ssd += weight[channel] * dis; 49 | } 50 | distance += ssd; 51 | } 52 | } 53 | //distance = 0; 54 | float result = (distance * 1.0f / weight_sum); 55 | return (ushort)(65535 * result); 56 | } 57 | 58 | 59 | __kernel void jumpFlooding(__global const char* source, __global const char* target, __global ushort* oldNNF, __global ushort* oldDistance, 60 | const uint4 imageSize, __global const uchar* mask) 61 | { 62 | 63 | int row = get_global_id(0); 64 | int col = get_global_id(1); 65 | 66 | int ROW[8]; 67 | int COL[8]; 68 | 69 | int window_radius = imageSize.z * 2; 70 | 71 | int knn = imageSize.w; 72 | if(knn > 16) 73 | knn = 16; 74 | 75 | int NNFOFFSET = imageSize.x * imageSize.y * 3; 76 | int DISOFFSET = imageSize.x * imageSize.y; 77 | 78 | int rows[9 * 17]; 79 | int cols[9 * 17]; 80 | int dis[9 * 17]; 81 | 82 | int iternum = 1; 83 | for(int iter = 0; iter < iternum; iter++){ 84 | if(iter == 1){ 85 | window_radius = 4; 86 | } 87 | while(window_radius > 0){ 88 | window_radius /= 2; 89 | 90 | ROW[0] = row - window_radius; 91 | COL[0] = col - window_radius; 92 | 93 | ROW[1] = row - window_radius; 94 | COL[1] = col; 95 | 96 | ROW[2] = row - window_radius; 97 | COL[2] = col + window_radius; 98 | 99 | ROW[3] = row; 100 | COL[3] = col - window_radius; 101 | 102 | ROW[4] = row; 103 | COL[4] = col + window_radius; 104 | 105 | ROW[5] = row + window_radius; 106 | COL[5] = col - window_radius; 107 | 108 | ROW[6] = row + window_radius; 109 | COL[6] = col; 110 | 111 | ROW[7] = row + window_radius; 112 | COL[7] = col + window_radius; 113 | 114 | //ROW[8] = row; 115 | //COL[8] = col; 116 | 117 | //int target_row = row; 118 | //int target_col = col; 119 | 120 | 121 | int k = 0; 122 | 123 | dis[k] = computeDistance(target, row, col, source, row, col, imageSize, mask); 124 | rows[k] = row; 125 | cols[k] = col; 126 | k++; 127 | 128 | 129 | for(int i = 0; i < knn; i++){ 130 | dis[k] = oldDistance[i * DISOFFSET + row * imageSize.y + col]; 131 | rows[k] = oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3 + 1]; 132 | cols[k] = oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3]; 133 | k++; 134 | } 135 | for(int i = 0; i < 8; i++){ 136 | if(ROW[i] < 0 || COL[i] < 0 || ROW[i] >= imageSize.x || COL[i] >= imageSize.y) 137 | continue; 138 | if(ROW[i] < 0) ROW[i] = 0; 139 | if(ROW[i] >= imageSize.x) ROW[i] = imageSize.x - 1; 140 | if(COL[i] < 0) COL[i] = 0; 141 | if(COL[i] >= imageSize.y) COL[i] = imageSize.y - 1; 142 | 143 | dis[k] = computeDistance(target, row, col, source, ROW[i], COL[i], imageSize, mask); 144 | rows[k] = ROW[i]; 145 | cols[k] = COL[i]; 146 | k++; 147 | 148 | for(int j = 0; j < knn; j++){ 149 | int currentRow = oldNNF[j * NNFOFFSET + ROW[i] * imageSize.y * 3 + COL[i] * 3 + 1] + row - ROW[i]; 150 | int currentCol = oldNNF[j * NNFOFFSET + ROW[i] * imageSize.y * 3 + COL[i] * 3] + col - COL[i]; 151 | 152 | dis[k] = computeDistance(target, row, col, source, currentRow, currentCol, imageSize, mask); 153 | rows[k] = currentRow; 154 | cols[k] = currentCol; 155 | k++; 156 | } 157 | } 158 | for(int i = 0; i < knn; i++){ 159 | for(int j = i + 1; j < k; j++){ 160 | if(rows[i] == rows[j] && cols[i] == cols[j]){ 161 | ushort c = dis[j]; 162 | dis[j] = dis[k-1]; 163 | dis[k-1] = c; 164 | 165 | c = rows[k-1]; 166 | rows[k-1] = rows[j]; 167 | rows[j] = c; 168 | 169 | c = cols[k-1]; 170 | cols[k-1] = cols[j]; 171 | cols[j] = c; 172 | k--; 173 | j--; 174 | continue; 175 | } 176 | if(dis[i] > dis[j]){ 177 | ushort c = dis[j]; 178 | dis[j] = dis[i]; 179 | dis[i] = c; 180 | 181 | c = rows[i]; 182 | rows[i] = rows[j]; 183 | rows[j] = c; 184 | 185 | c = cols[i]; 186 | cols[i] = cols[j]; 187 | cols[j] = c; 188 | } 189 | 190 | } 191 | } 192 | 193 | barrier(CLK_LOCAL_MEM_FENCE); 194 | for(int i = 0; i < knn; i++){ 195 | oldDistance[i * DISOFFSET + row * imageSize.y + col] = dis[i]; 196 | oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3] = cols[i]; 197 | oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3 + 1] = rows[i]; 198 | } 199 | barrier(CLK_LOCAL_MEM_FENCE); 200 | 201 | } 202 | } 203 | //if(mask[row * imageSize.y + col] != 0){ 204 | // oldNNF[row * imageSize.y * 3 + col * 3] = col - 50; 205 | // oldNNF[row * imageSize.y * 3 + col * 3 + 1] = row; 206 | //} 207 | 208 | 209 | } -------------------------------------------------------------------------------- /ImageWorkShop/openclShader/jumpFloodingCopy.cl: -------------------------------------------------------------------------------- 1 | ushort computeDistance( __global const uchar* target, int target_row, int target_col, __global const uchar* source, 2 | int source_row, int source_col, const uint4 imageSize){ 3 | long distance = 0; 4 | long weight_sum = 0; 5 | int penalty = 655350; 6 | int radius = 2; 7 | for(int dy =- radius; dy <= radius; dy++) { 8 | for(int dx =- radius; dx <= radius; dx++) { 9 | weight_sum += penalty; 10 | 11 | int s_row = source_row + dy; 12 | int s_col = source_col + dx; 13 | if (s_row < 0 || s_row >= imageSize.x){ 14 | distance += penalty; 15 | continue; 16 | } 17 | 18 | if (s_col < 0 || s_col >= imageSize.y){ 19 | distance += penalty; 20 | continue; 21 | } 22 | 23 | int t_row= target_row + dy; 24 | int t_col = target_col + dx; 25 | if (t_row < 0 || t_row >= imageSize.x){ 26 | distance += penalty; 27 | continue; 28 | } 29 | if (t_col < 0 || t_col >= imageSize.y){ 30 | distance += penalty; 31 | continue; 32 | } 33 | 34 | 35 | //compute ssd 36 | long ssd = 0; 37 | int weight[3] = {1, 6, 3}; 38 | for(int channel = 0; channel < 3; channel++){ 39 | int s = source[s_row * imageSize.y * 3 + s_col * 3 + channel]; 40 | int t = target[t_row * imageSize.y * 3 + t_col * 3 + channel]; 41 | float dis = (s - t) * (s - t); // Value 42 | ssd += weight[channel] * dis; 43 | } 44 | distance += ssd; 45 | } 46 | } 47 | //distance = 0; 48 | float result = (distance * 1.0f / weight_sum); 49 | return (ushort)(65535 * result); 50 | } 51 | 52 | 53 | __kernel void jumpFloodingCopy(__global const char* source, __global const char* target, __global ushort* oldNNF, __global ushort* oldDistance, 54 | const uint4 imageSize, __global const uchar* mask) 55 | { 56 | 57 | int row = get_global_id(0); 58 | int col = get_global_id(1); 59 | 60 | int ROW[8]; 61 | int COL[8]; 62 | 63 | int window_radius = imageSize.z * 2; 64 | 65 | int knn = imageSize.w; 66 | if(knn > 16) 67 | knn = 16; 68 | 69 | int NNFOFFSET = imageSize.x * imageSize.y * 3; 70 | int DISOFFSET = imageSize.x * imageSize.y; 71 | 72 | int rows[9 * 17]; 73 | int cols[9 * 17]; 74 | int dis[9 * 17]; 75 | 76 | int iternum = 1; 77 | for(int iter = 0; iter < iternum; iter++){ 78 | if(iter == 1){ 79 | window_radius = 4; 80 | } 81 | while(window_radius > 0){ 82 | window_radius /= 2; 83 | if(mask[row * imageSize.y + col] == 0) 84 | { 85 | ROW[0] = row - window_radius; 86 | COL[0] = col - window_radius; 87 | 88 | ROW[1] = row - window_radius; 89 | COL[1] = col; 90 | 91 | ROW[2] = row - window_radius; 92 | COL[2] = col + window_radius; 93 | 94 | ROW[3] = row; 95 | COL[3] = col - window_radius; 96 | 97 | ROW[4] = row; 98 | COL[4] = col + window_radius; 99 | 100 | ROW[5] = row + window_radius; 101 | COL[5] = col - window_radius; 102 | 103 | ROW[6] = row + window_radius; 104 | COL[6] = col; 105 | 106 | ROW[7] = row + window_radius; 107 | COL[7] = col + window_radius; 108 | 109 | //ROW[8] = row; 110 | //COL[8] = col; 111 | 112 | //int target_row = row; 113 | //int target_col = col; 114 | 115 | 116 | int k = 0; 117 | 118 | dis[k] = computeDistance(target, row, col, source, row, col, imageSize); 119 | rows[k] = row; 120 | cols[k] = col; 121 | k++; 122 | 123 | 124 | for(int i = 0; i < knn; i++){ 125 | dis[k] = oldDistance[i * DISOFFSET + row * imageSize.y + col]; 126 | rows[k] = oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3 + 1]; 127 | cols[k] = oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3]; 128 | k++; 129 | } 130 | for(int i = 0; i < 8; i++){ 131 | if(ROW[i] < 0 || COL[i] < 0 || ROW[i] >= imageSize.x || COL[i] >= imageSize.y) 132 | continue; 133 | if(ROW[i] < 0) ROW[i] = 0; 134 | if(ROW[i] >= imageSize.x) ROW[i] = imageSize.x - 1; 135 | if(COL[i] < 0) COL[i] = 0; 136 | if(COL[i] >= imageSize.y) COL[i] = imageSize.y - 1; 137 | 138 | dis[k] = computeDistance(target, row, col, source, ROW[i], COL[i], imageSize); 139 | rows[k] = ROW[i]; 140 | cols[k] = COL[i]; 141 | k++; 142 | 143 | for(int j = 0; j < knn; j++){ 144 | int currentRow = oldNNF[j * NNFOFFSET + ROW[i] * imageSize.y * 3 + COL[i] * 3 + 1] + row - ROW[i]; 145 | int currentCol = oldNNF[j * NNFOFFSET + ROW[i] * imageSize.y * 3 + COL[i] * 3] + col - COL[i]; 146 | 147 | dis[k] = computeDistance(target, row, col, source, currentRow, currentCol, imageSize); 148 | rows[k] = currentRow; 149 | cols[k] = currentCol; 150 | k++; 151 | } 152 | } 153 | for(int i = 0; i < knn; i++){ 154 | for(int j = i + 1; j < k; j++){ 155 | if(rows[i] == rows[j] && cols[i] == cols[j]){ 156 | ushort c = dis[j]; 157 | dis[j] = dis[k-1]; 158 | dis[k-1] = c; 159 | 160 | c = rows[k-1]; 161 | rows[k-1] = rows[j]; 162 | rows[j] = c; 163 | 164 | c = cols[k-1]; 165 | cols[k-1] = cols[j]; 166 | cols[j] = c; 167 | k--; 168 | j--; 169 | continue; 170 | } 171 | if(dis[i] > dis[j]){ 172 | ushort c = dis[j]; 173 | dis[j] = dis[i]; 174 | dis[i] = c; 175 | 176 | c = rows[i]; 177 | rows[i] = rows[j]; 178 | rows[j] = c; 179 | 180 | c = cols[i]; 181 | cols[i] = cols[j]; 182 | cols[j] = c; 183 | } 184 | 185 | } 186 | } 187 | } 188 | barrier(CLK_LOCAL_MEM_FENCE); 189 | if(mask[row * imageSize.y + col] == 0){ 190 | for(int i = 0; i < knn; i++){ 191 | oldDistance[i * DISOFFSET + row * imageSize.y + col] = dis[i]; 192 | oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3] = cols[i]; 193 | oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3 + 1] = rows[i]; 194 | } 195 | } 196 | barrier(CLK_LOCAL_MEM_FENCE); 197 | 198 | } 199 | } 200 | //if(mask[row * imageSize.y + col] != 0){ 201 | // oldNNF[row * imageSize.y * 3 + col * 3] = col - 50; 202 | // oldNNF[row * imageSize.y * 3 + col * 3 + 1] = row; 203 | //} 204 | 205 | 206 | } -------------------------------------------------------------------------------- /ImageWorkShop/openclShader/jumpFloodingRestrict.cl: -------------------------------------------------------------------------------- 1 | ushort computeDistance( __global const uchar* target, int target_row, int target_col, __global const uchar* source, 2 | int source_row, int source_col, const uint4 imageSize, __global const uchar* mask, __global const uchar* currentRestrict){ 3 | long distance = 0; 4 | long weight_sum = 0; 5 | int penalty = 655350; 6 | int radius = 2; 7 | for(int dy =- radius; dy <= radius; dy++) { 8 | for(int dx =- radius; dx <= radius; dx++) { 9 | weight_sum += penalty; 10 | 11 | int s_row = source_row + dy; 12 | int s_col = source_col + dx; 13 | if (s_row < 0 || s_row >= imageSize.x){ 14 | distance += penalty; 15 | continue; 16 | } 17 | 18 | if (s_col < 0 || s_col >= imageSize.y){ 19 | distance += penalty; 20 | continue; 21 | } 22 | 23 | //penalty for hole in source 24 | if (mask[s_row * imageSize.y + s_col] != 0) { 25 | distance += penalty; 26 | continue; 27 | } 28 | 29 | int t_row= target_row + dy; 30 | int t_col = target_col + dx; 31 | if (t_row < 0 || t_row >= imageSize.x){ 32 | distance += penalty; 33 | continue; 34 | } 35 | if (t_col < 0 || t_col >= imageSize.y){ 36 | distance += penalty; 37 | continue; 38 | } 39 | 40 | if (mask[t_row * imageSize.y + t_col] != 0) { 41 | //判断source是否在restrict内部,若不在,则惩罚 42 | if(currentRestrict[s_row * imageSize.y + s_col] == 0){ 43 | distance += penalty; 44 | continue; 45 | } 46 | } 47 | 48 | 49 | //compute ssd 50 | long ssd = 0; 51 | int weight[3] = {1, 6, 3}; 52 | for(int channel = 0; channel < 3; channel++){ 53 | int s = source[s_row * imageSize.y * 3 + s_col * 3 + channel]; 54 | int t = target[t_row * imageSize.y * 3 + t_col * 3 + channel]; 55 | float dis = (s - t) * (s - t); // Value 56 | ssd += weight[channel] * dis; 57 | } 58 | distance += ssd; 59 | } 60 | } 61 | //distance = 0; 62 | float result = (distance * 1.0f / weight_sum); 63 | return (ushort)(65535 * result); 64 | } 65 | 66 | 67 | __kernel void jumpFloodingRestrict(__global const char* source, __global const char* target, __global ushort* oldNNF, __global ushort* oldDistance, 68 | const uint4 imageSize, __global const uchar* mask, __global const uchar* currentRestrict) 69 | { 70 | 71 | int row = get_global_id(0); 72 | int col = get_global_id(1); 73 | 74 | int ROW[8]; 75 | int COL[8]; 76 | 77 | int window_radius = imageSize.z * 2; 78 | 79 | int knn = imageSize.w; 80 | if(knn > 16) 81 | knn = 16; 82 | 83 | int NNFOFFSET = imageSize.x * imageSize.y * 3; 84 | int DISOFFSET = imageSize.x * imageSize.y; 85 | 86 | int rows[9 * 17]; 87 | int cols[9 * 17]; 88 | int dis[9 * 17]; 89 | 90 | int iternum = 1; 91 | for(int iter = 0; iter < iternum; iter++){ 92 | if(iter == 1){ 93 | window_radius = 4; 94 | } 95 | while(window_radius > 0){ 96 | window_radius /= 2; 97 | 98 | ROW[0] = row - window_radius; 99 | COL[0] = col - window_radius; 100 | 101 | ROW[1] = row - window_radius; 102 | COL[1] = col; 103 | 104 | ROW[2] = row - window_radius; 105 | COL[2] = col + window_radius; 106 | 107 | ROW[3] = row; 108 | COL[3] = col - window_radius; 109 | 110 | ROW[4] = row; 111 | COL[4] = col + window_radius; 112 | 113 | ROW[5] = row + window_radius; 114 | COL[5] = col - window_radius; 115 | 116 | ROW[6] = row + window_radius; 117 | COL[6] = col; 118 | 119 | ROW[7] = row + window_radius; 120 | COL[7] = col + window_radius; 121 | 122 | //ROW[8] = row; 123 | //COL[8] = col; 124 | 125 | //int target_row = row; 126 | //int target_col = col; 127 | 128 | 129 | int k = 0; 130 | 131 | dis[k] = computeDistance(target, row, col, source, row, col, imageSize, mask, currentRestrict); 132 | rows[k] = row; 133 | cols[k] = col; 134 | k++; 135 | 136 | 137 | for(int i = 0; i < knn; i++){ 138 | dis[k] = oldDistance[i * DISOFFSET + row * imageSize.y + col]; 139 | rows[k] = oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3 + 1]; 140 | cols[k] = oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3]; 141 | k++; 142 | } 143 | for(int i = 0; i < 8; i++){ 144 | if(ROW[i] < 0 || COL[i] < 0 || ROW[i] >= imageSize.x || COL[i] >= imageSize.y) 145 | continue; 146 | if(ROW[i] < 0) ROW[i] = 0; 147 | if(ROW[i] >= imageSize.x) ROW[i] = imageSize.x - 1; 148 | if(COL[i] < 0) COL[i] = 0; 149 | if(COL[i] >= imageSize.y) COL[i] = imageSize.y - 1; 150 | 151 | dis[k] = computeDistance(target, row, col, source, ROW[i], COL[i], imageSize, mask, currentRestrict); 152 | rows[k] = ROW[i]; 153 | cols[k] = COL[i]; 154 | k++; 155 | 156 | for(int j = 0; j < knn; j++){ 157 | int currentRow = oldNNF[j * NNFOFFSET + ROW[i] * imageSize.y * 3 + COL[i] * 3 + 1] + row - ROW[i]; 158 | int currentCol = oldNNF[j * NNFOFFSET + ROW[i] * imageSize.y * 3 + COL[i] * 3] + col - COL[i]; 159 | 160 | dis[k] = computeDistance(target, row, col, source, currentRow, currentCol, imageSize, mask, currentRestrict); 161 | rows[k] = currentRow; 162 | cols[k] = currentCol; 163 | k++; 164 | } 165 | } 166 | for(int i = 0; i < knn; i++){ 167 | for(int j = i + 1; j < k; j++){ 168 | if(rows[i] == rows[j] && cols[i] == cols[j]){ 169 | ushort c = dis[j]; 170 | dis[j] = dis[k-1]; 171 | dis[k-1] = c; 172 | 173 | c = rows[k-1]; 174 | rows[k-1] = rows[j]; 175 | rows[j] = c; 176 | 177 | c = cols[k-1]; 178 | cols[k-1] = cols[j]; 179 | cols[j] = c; 180 | k--; 181 | j--; 182 | continue; 183 | } 184 | if(dis[i] > dis[j]){ 185 | ushort c = dis[j]; 186 | dis[j] = dis[i]; 187 | dis[i] = c; 188 | 189 | c = rows[i]; 190 | rows[i] = rows[j]; 191 | rows[j] = c; 192 | 193 | c = cols[i]; 194 | cols[i] = cols[j]; 195 | cols[j] = c; 196 | } 197 | 198 | } 199 | } 200 | 201 | barrier(CLK_LOCAL_MEM_FENCE); 202 | for(int i = 0; i < knn; i++){ 203 | oldDistance[i * DISOFFSET + row * imageSize.y + col] = dis[i]; 204 | oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3] = cols[i]; 205 | oldNNF[i * NNFOFFSET + row * imageSize.y * 3 + col * 3 + 1] = rows[i]; 206 | } 207 | barrier(CLK_LOCAL_MEM_FENCE); 208 | 209 | } 210 | } 211 | //if(mask[row * imageSize.y + col] != 0){ 212 | // oldNNF[row * imageSize.y * 3 + col * 3] = col - 50; 213 | // oldNNF[row * imageSize.y * 3 + col * 3 + 1] = row; 214 | //} 215 | 216 | 217 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ImageWorkShop 2 | MeiTu+PatchMatch Visual Studio2012 Qt5.4.1 opencv2.4.11 3 | 4 | MeiTu: 5 | gauss filter, median filter, sharp, 6 | white balence, saturation, liquigy, lomo style, vignette, 7 | skin dermabrasion and whitening 8 | 9 | PatchMatch: 10 | propagation and random search CPU 11 | jump flooding GPU OpenCL 12 | 13 | colorization: 14 | Welsh T, Ashikhmin M, Mueller K. Transferring color to greyscale images[J]. 15 | ACM Transactions on Graphics (TOG), 2002, 21(3): 277-280. -------------------------------------------------------------------------------- /filter_intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunsiy10/ImageWorkShop/14013beccab1f7b6894cac92e2f312c2ef622589/filter_intro.pdf -------------------------------------------------------------------------------- /patchmatch_intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunsiy10/ImageWorkShop/14013beccab1f7b6894cac92e2f312c2ef622589/patchmatch_intro.pdf --------------------------------------------------------------------------------