├── README.md ├── algorithms ├── Canny Filter │ ├── .idea │ │ ├── description.html │ │ ├── misc.xml │ │ ├── modules.xml │ │ ├── project-template.xml │ │ ├── uiDesigner.xml │ │ └── workspace.xml │ ├── Canny Filter.iml │ ├── Images │ │ ├── output.jpg │ │ └── photo.jpg │ ├── out │ │ └── production │ │ │ └── Canny Filter │ │ │ └── com │ │ │ └── company │ │ │ ├── CannyFilter.class │ │ │ └── Main.class │ └── src │ │ └── com │ │ └── company │ │ ├── CannyFilter.java │ │ └── Main.java ├── MedianFIlter │ ├── .idea │ │ ├── description.html │ │ ├── misc.xml │ │ ├── modules.xml │ │ ├── project-template.xml │ │ └── workspace.xml │ ├── Images │ │ ├── output.jpg │ │ └── photo.jpg │ ├── MedianFIlter.iml │ ├── out │ │ └── production │ │ │ └── MedianFIlter │ │ │ └── com │ │ │ └── company │ │ │ └── Main.class │ └── src │ │ └── com │ │ └── company │ │ └── Main.java └── MirrorFIlter │ ├── .idea │ ├── misc.xml │ ├── modules.xml │ └── workspace.xml │ ├── Images │ ├── output.jpg │ └── photo.jpg │ ├── MirrorFIlter.iml │ ├── out │ └── production │ │ └── MirrorFIlter │ │ └── MirrorFilter.class │ └── src │ └── MirrorFilter.java ├── android ├── .gitignore ├── .idea │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── gradle.xml │ ├── misc.xml │ ├── modules.xml │ └── runConfigurations.xml ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── imageprocessing │ │ │ └── enzoftware │ │ │ └── imageprocessingapp │ │ │ ├── Canny.java │ │ │ └── MainActivity.java │ │ └── res │ │ ├── drawable │ │ ├── love.png │ │ ├── metalprocessing.png │ │ └── p_icon_01.png │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle └── desktop ├── .vs └── Histograma Local │ ├── v14 │ └── .suo │ └── v15 │ └── .suo ├── Histograma Local.sln ├── Histograma Local.v12.suo └── Histograma Local ├── Algorithms.cs ├── App.config ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Histograma Local.csproj ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── Resources ├── 1448138637_filesave.png ├── 1448139329_image.png └── 1448139488_folder.png ├── bin ├── Debug │ ├── Histograma Local.exe │ ├── Histograma Local.exe.config │ ├── Histograma Local.pdb │ ├── Histograma Local.vshost.exe │ ├── Histograma Local.vshost.exe.config │ └── Histograma Local.vshost.exe.manifest └── Release │ ├── Histograma Local.exe │ ├── Histograma Local.exe.config │ ├── Histograma Local.pdb │ ├── Histograma Local.vshost.exe │ ├── Histograma Local.vshost.exe.config │ └── Histograma Local.vshost.exe.manifest └── obj ├── Debug ├── CoreCompileInputs.cache ├── DesignTimeResolveAssemblyReferences.cache ├── DesignTimeResolveAssemblyReferencesInput.cache ├── Histograma Local.csproj.FileListAbsolute.txt ├── Histograma Local.csproj.GenerateResource.Cache ├── Histograma Local.csprojResolveAssemblyReference.cache ├── Histograma Local.exe ├── Histograma Local.pdb ├── Histograma_Local.Form1.resources ├── Histograma_Local.Properties.Resources.resources ├── TempPE │ └── Properties.Resources.Designer.cs.dll ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs └── Release ├── DesignTimeResolveAssemblyReferences.cache ├── DesignTimeResolveAssemblyReferencesInput.cache ├── Histograma Local.csproj.FileListAbsolute.txt ├── Histograma Local.csproj.GenerateResource.Cache ├── Histograma Local.csprojResolveAssemblyReference.cache ├── Histograma Local.exe ├── Histograma Local.pdb ├── Histograma_Local.Form1.resources ├── Histograma_Local.Properties.Resources.resources ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![image processing](https://www.gdpicture.com/wp-content/uploads/image-processing.png) 4 | 5 | # Image processing 6 | --- 7 | Project for the computer mathematics course of the Peruvian University of Applied Sciences - 3rd cycle 8 | 9 |
10 | 11 | 12 | ### Canny Filter - Edge detection 13 | 14 | 15 |
16 | 17 | 18 | ![canny filter](https://docs.opencv.org/3.4.0/canny1.jpg) 19 | 20 | 21 |
22 | 23 | ### Median Filter 24 | El filtro de la mediana trabaja de la manera siguiente para poder asignar los valores a cada pixel de la nueva imagen 25 | 26 |
27 | 28 | 29 | ![median filter](http://artemhlezin.com/images/posts/median/median.gif) 30 | 31 | ![median filter](http://in.mathworks.com/matlabcentral/mlc-downloads/downloads/submissions/16201/versions/3/previews/toolbox_image/html/content_08.png) 32 | 33 | 34 |
35 | 36 | ### Mirror Filter - Selfie effect 37 | -------------------------------------------------------------------------------- /algorithms/Canny Filter/.idea/description.html: -------------------------------------------------------------------------------- 1 | Simple Java application that includes a class with main() method -------------------------------------------------------------------------------- /algorithms/Canny Filter/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /algorithms/Canny Filter/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithms/Canny Filter/.idea/project-template.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /algorithms/Canny Filter/.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /algorithms/Canny Filter/Canny Filter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /algorithms/Canny Filter/Images/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/Canny Filter/Images/output.jpg -------------------------------------------------------------------------------- /algorithms/Canny Filter/Images/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/Canny Filter/Images/photo.jpg -------------------------------------------------------------------------------- /algorithms/Canny Filter/out/production/Canny Filter/com/company/CannyFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/Canny Filter/out/production/Canny Filter/com/company/CannyFilter.class -------------------------------------------------------------------------------- /algorithms/Canny Filter/out/production/Canny Filter/com/company/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/Canny Filter/out/production/Canny Filter/com/company/Main.class -------------------------------------------------------------------------------- /algorithms/Canny Filter/src/com/company/CannyFilter.java: -------------------------------------------------------------------------------- 1 | package com.company; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.util.Arrays; 5 | 6 | public class CannyFilter { 7 | 8 | 9 | 10 | private final static float GAUSSIAN_CUT_OFF = 0.005f; 11 | private final static float MAGNITUDE_SCALE = 100F; 12 | private final static float MAGNITUDE_LIMIT = 1000F; 13 | private final static int MAGNITUDE_MAX = (int) (MAGNITUDE_SCALE * MAGNITUDE_LIMIT); 14 | 15 | 16 | 17 | private int height; 18 | private int width; 19 | private int picsize; 20 | private int[] data; 21 | private int[] magnitude; 22 | private BufferedImage sourceImage; 23 | private BufferedImage edgesImage; 24 | 25 | private float gaussianKernelRadius; 26 | private float lowThreshold; 27 | private float highThreshold; 28 | private int gaussianKernelWidth; 29 | private boolean contrastNormalized; 30 | 31 | private float[] xConv; 32 | private float[] yConv; 33 | private float[] xGradient; 34 | private float[] yGradient; 35 | 36 | 37 | public CannyFilter() { 38 | lowThreshold = 2.5f; 39 | highThreshold = 7.5f; 40 | gaussianKernelRadius = 2f; 41 | gaussianKernelWidth = 16; 42 | contrastNormalized = false; 43 | } 44 | 45 | 46 | 47 | public BufferedImage getSourceImage() { 48 | return sourceImage; 49 | } 50 | 51 | 52 | public void setSourceImage(BufferedImage image) { 53 | sourceImage = image; 54 | } 55 | 56 | 57 | 58 | public BufferedImage getEdgesImage() { 59 | return edgesImage; 60 | } 61 | 62 | 63 | 64 | public void setEdgesImage(BufferedImage edgesImage) { 65 | this.edgesImage = edgesImage; 66 | } 67 | 68 | 69 | 70 | public float getLowThreshold() { 71 | return lowThreshold; 72 | } 73 | 74 | 75 | public void setLowThreshold(float threshold) { 76 | if (threshold < 0) throw new IllegalArgumentException(); 77 | lowThreshold = threshold; 78 | } 79 | 80 | 81 | public float getHighThreshold() { 82 | return highThreshold; 83 | } 84 | 85 | 86 | 87 | public void setHighThreshold(float threshold) { 88 | if (threshold < 0) throw new IllegalArgumentException(); 89 | highThreshold = threshold; 90 | } 91 | 92 | 93 | 94 | public int getGaussianKernelWidth() { 95 | return gaussianKernelWidth; 96 | } 97 | 98 | 99 | 100 | public void setGaussianKernelWidth(int gaussianKernelWidth) { 101 | if (gaussianKernelWidth < 2) throw new IllegalArgumentException(); 102 | this.gaussianKernelWidth = gaussianKernelWidth; 103 | } 104 | 105 | 106 | public float getGaussianKernelRadius() { 107 | return gaussianKernelRadius; 108 | } 109 | 110 | 111 | public void setGaussianKernelRadius(float gaussianKernelRadius) { 112 | if (gaussianKernelRadius < 0.1f) throw new IllegalArgumentException(); 113 | this.gaussianKernelRadius = gaussianKernelRadius; 114 | } 115 | 116 | 117 | public boolean isContrastNormalized() { 118 | return contrastNormalized; 119 | } 120 | 121 | 122 | 123 | public void setContrastNormalized(boolean contrastNormalized) { 124 | this.contrastNormalized = contrastNormalized; 125 | } 126 | 127 | 128 | 129 | public void process() { 130 | width = sourceImage.getWidth(); 131 | height = sourceImage.getHeight(); 132 | picsize = width * height; 133 | initArrays(); 134 | readLuminance(); 135 | if (contrastNormalized) normalizeContrast(); 136 | computeGradients(gaussianKernelRadius, gaussianKernelWidth); 137 | int low = Math.round(lowThreshold * MAGNITUDE_SCALE); 138 | int high = Math.round( highThreshold * MAGNITUDE_SCALE); 139 | performHysteresis(low, high); 140 | thresholdEdges(); 141 | writeEdges(data); 142 | } 143 | 144 | 145 | 146 | private void initArrays() { 147 | if (data == null || picsize != data.length) { 148 | data = new int[picsize]; 149 | magnitude = new int[picsize]; 150 | 151 | xConv = new float[picsize]; 152 | yConv = new float[picsize]; 153 | xGradient = new float[picsize]; 154 | yGradient = new float[picsize]; 155 | } 156 | } 157 | 158 | 159 | 160 | private void computeGradients(float kernelRadius, int kernelWidth) { 161 | 162 | float kernel[] = new float[kernelWidth]; 163 | float diffKernel[] = new float[kernelWidth]; 164 | int kwidth; 165 | for (kwidth = 0; kwidth < kernelWidth; kwidth++) { 166 | float g1 = gaussian(kwidth, kernelRadius); 167 | if (g1 <= GAUSSIAN_CUT_OFF && kwidth >= 2) break; 168 | float g2 = gaussian(kwidth - 0.5f, kernelRadius); 169 | float g3 = gaussian(kwidth + 0.5f, kernelRadius); 170 | kernel[kwidth] = (g1 + g2 + g3) / 3f / (2f * (float) Math.PI * kernelRadius * kernelRadius); 171 | diffKernel[kwidth] = g3 - g2; 172 | } 173 | 174 | int initX = kwidth - 1; 175 | int maxX = width - (kwidth - 1); 176 | int initY = width * (kwidth - 1); 177 | int maxY = width * (height - (kwidth - 1)); 178 | 179 | //perform convolution in x and y directions 180 | for (int x = initX; x < maxX; x++) { 181 | for (int y = initY; y < maxY; y += width) { 182 | int index = x + y; 183 | float sumX = data[index] * kernel[0]; 184 | float sumY = sumX; 185 | int xOffset = 1; 186 | int yOffset = width; 187 | for(; xOffset < kwidth ;) { 188 | sumY += kernel[xOffset] * (data[index - yOffset] + data[index + yOffset]); 189 | sumX += kernel[xOffset] * (data[index - xOffset] + data[index + xOffset]); 190 | yOffset += width; 191 | xOffset++; 192 | } 193 | 194 | yConv[index] = sumY; 195 | xConv[index] = sumX; 196 | } 197 | 198 | } 199 | 200 | for (int x = initX; x < maxX; x++) { 201 | for (int y = initY; y < maxY; y += width) { 202 | float sum = 0f; 203 | int index = x + y; 204 | for (int i = 1; i < kwidth; i++) 205 | sum += diffKernel[i] * (yConv[index - i] - yConv[index + i]); 206 | 207 | xGradient[index] = sum; 208 | } 209 | 210 | } 211 | 212 | for (int x = kwidth; x < width - kwidth; x++) { 213 | for (int y = initY; y < maxY; y += width) { 214 | float sum = 0.0f; 215 | int index = x + y; 216 | int yOffset = width; 217 | for (int i = 1; i < kwidth; i++) { 218 | sum += diffKernel[i] * (xConv[index - yOffset] - xConv[index + yOffset]); 219 | yOffset += width; 220 | } 221 | 222 | yGradient[index] = sum; 223 | } 224 | 225 | } 226 | 227 | initX = kwidth; 228 | maxX = width - kwidth; 229 | initY = width * kwidth; 230 | maxY = width * (height - kwidth); 231 | for (int x = initX; x < maxX; x++) { 232 | for (int y = initY; y < maxY; y += width) { 233 | int index = x + y; 234 | int indexN = index - width; 235 | int indexS = index + width; 236 | int indexW = index - 1; 237 | int indexE = index + 1; 238 | int indexNW = indexN - 1; 239 | int indexNE = indexN + 1; 240 | int indexSW = indexS - 1; 241 | int indexSE = indexS + 1; 242 | 243 | float xGrad = xGradient[index]; 244 | float yGrad = yGradient[index]; 245 | float gradMag = hypot(xGrad, yGrad); 246 | 247 | //perform non-maximal supression 248 | float nMag = hypot(xGradient[indexN], yGradient[indexN]); 249 | float sMag = hypot(xGradient[indexS], yGradient[indexS]); 250 | float wMag = hypot(xGradient[indexW], yGradient[indexW]); 251 | float eMag = hypot(xGradient[indexE], yGradient[indexE]); 252 | float neMag = hypot(xGradient[indexNE], yGradient[indexNE]); 253 | float seMag = hypot(xGradient[indexSE], yGradient[indexSE]); 254 | float swMag = hypot(xGradient[indexSW], yGradient[indexSW]); 255 | float nwMag = hypot(xGradient[indexNW], yGradient[indexNW]); 256 | float tmp; 257 | 258 | if (xGrad * yGrad <= (float) 0 /*(1)*/ 259 | ? Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/ 260 | ? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * neMag - (xGrad + yGrad) * eMag) /*(3)*/ 261 | && tmp > Math.abs(yGrad * swMag - (xGrad + yGrad) * wMag) /*(4)*/ 262 | : (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * neMag - (yGrad + xGrad) * nMag) /*(3)*/ 263 | && tmp > Math.abs(xGrad * swMag - (yGrad + xGrad) * sMag) /*(4)*/ 264 | : Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/ 265 | ? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * seMag + (xGrad - yGrad) * eMag) /*(3)*/ 266 | && tmp > Math.abs(yGrad * nwMag + (xGrad - yGrad) * wMag) /*(4)*/ 267 | : (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * seMag + (yGrad - xGrad) * sMag) /*(3)*/ 268 | && tmp > Math.abs(xGrad * nwMag + (yGrad - xGrad) * nMag) /*(4)*/ 269 | ) { 270 | magnitude[index] = gradMag >= MAGNITUDE_LIMIT ? MAGNITUDE_MAX : (int) (MAGNITUDE_SCALE * gradMag); 271 | 272 | } else { 273 | magnitude[index] = 0; 274 | } 275 | } 276 | } 277 | } 278 | 279 | private float hypot(float x, float y) { 280 | return (float) Math.hypot(x, y); 281 | } 282 | 283 | private float gaussian(float x, float sigma) { 284 | return (float) Math.exp(-(x * x) / (2f * sigma * sigma)); 285 | } 286 | 287 | private void performHysteresis(int low, int high) { 288 | 289 | Arrays.fill(data, 0); 290 | 291 | int offset = 0; 292 | for (int y = 0; y < height; y++) { 293 | for (int x = 0; x < width; x++) { 294 | if (data[offset] == 0 && magnitude[offset] >= high) { 295 | follow(x, y, offset, low); 296 | } 297 | offset++; 298 | } 299 | } 300 | } 301 | 302 | private void follow(int x1, int y1, int i1, int threshold) { 303 | int x0 = x1 == 0 ? x1 : x1 - 1; 304 | int x2 = x1 == width - 1 ? x1 : x1 + 1; 305 | int y0 = y1 == 0 ? y1 : y1 - 1; 306 | int y2 = y1 == height -1 ? y1 : y1 + 1; 307 | 308 | data[i1] = magnitude[i1]; 309 | for (int x = x0; x <= x2; x++) { 310 | for (int y = y0; y <= y2; y++) { 311 | int i2 = x + y * width; 312 | if ((y != y1 || x != x1) 313 | && data[i2] == 0 314 | && magnitude[i2] >= threshold) { 315 | follow(x, y, i2, threshold); 316 | return; 317 | } 318 | } 319 | } 320 | } 321 | 322 | private void thresholdEdges() { 323 | for (int i = 0; i < picsize; i++) { 324 | data[i] = data[i] > 0 ? -1 : 0xff000000; 325 | } 326 | } 327 | 328 | private int luminance(float r, float g, float b) { 329 | return Math.round(0.299f * r + 0.587f * g + 0.114f * b); 330 | } 331 | 332 | private void readLuminance() { 333 | int type = sourceImage.getType(); 334 | if (type == BufferedImage.TYPE_INT_RGB || type == BufferedImage.TYPE_INT_ARGB) { 335 | int[] pixels = (int[]) sourceImage.getData().getDataElements(0, 0, width, height, null); 336 | for (int i = 0; i < picsize; i++) { 337 | int p = pixels[i]; 338 | int r = (p & 0xff0000) >> 16; 339 | int g = (p & 0xff00) >> 8; 340 | int b = p & 0xff; 341 | data[i] = luminance(r, g, b); 342 | } 343 | } else if (type == BufferedImage.TYPE_BYTE_GRAY) { 344 | byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, width, height, null); 345 | for (int i = 0; i < picsize; i++) { 346 | data[i] = (pixels[i] & 0xff); 347 | } 348 | } else if (type == BufferedImage.TYPE_USHORT_GRAY) { 349 | short[] pixels = (short[]) sourceImage.getData().getDataElements(0, 0, width, height, null); 350 | for (int i = 0; i < picsize; i++) { 351 | data[i] = (pixels[i] & 0xffff) / 256; 352 | } 353 | } else if (type == BufferedImage.TYPE_3BYTE_BGR) { 354 | byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, width, height, null); 355 | int offset = 0; 356 | for (int i = 0; i < picsize; i++) { 357 | int b = pixels[offset++] & 0xff; 358 | int g = pixels[offset++] & 0xff; 359 | int r = pixels[offset++] & 0xff; 360 | data[i] = luminance(r, g, b); 361 | } 362 | } else { 363 | throw new IllegalArgumentException("Unsupported image type: " + type); 364 | } 365 | } 366 | 367 | private void normalizeContrast() { 368 | int[] histogram = new int[256]; 369 | for (int i = 0; i < data.length; i++) { 370 | histogram[data[i]]++; 371 | } 372 | int[] remap = new int[256]; 373 | int sum = 0; 374 | int j = 0; 375 | for (int i = 0; i < histogram.length; i++) { 376 | sum += histogram[i]; 377 | int target = sum*255/picsize; 378 | for (int k = j+1; k <=target; k++) { 379 | remap[k] = i; 380 | } 381 | j = target; 382 | } 383 | 384 | for (int i = 0; i < data.length; i++) { 385 | data[i] = remap[data[i]]; 386 | } 387 | } 388 | 389 | private void writeEdges(int pixels[]) { 390 | 391 | if (edgesImage == null) { 392 | edgesImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 393 | } 394 | edgesImage.getWritableTile(0, 0).setDataElements(0, 0, width, height, pixels); 395 | } 396 | 397 | } -------------------------------------------------------------------------------- /algorithms/Canny Filter/src/com/company/Main.java: -------------------------------------------------------------------------------- 1 | package com.company; 2 | import java.awt.image.ColorConvertOp; 3 | import javax.imageio.ImageIO; 4 | import java.awt.image.BufferedImage; 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | public class Main { 9 | public static void main(String args[]) throws IOException { 10 | BufferedImage photo= ImageIO.read(new File("Images/photo.jpg")); 11 | File output=new File("Images/output.jpg"); //Input Photo File 12 | //create the detector 13 | CannyFilter detector = new CannyFilter(); 14 | 15 | //adjust its parameters as desired 16 | detector.setLowThreshold(0.5f); 17 | detector.setHighThreshold(1f); 18 | 19 | //apply it to an image 20 | detector.setSourceImage(photo); 21 | detector.process(); 22 | BufferedImage edges = detector.getEdgesImage(); 23 | //ImageIO.write(edges,"JPG",output); 24 | BufferedImage rgbImage = new BufferedImage(edges.getWidth(), 25 | edges.getHeight(), BufferedImage.TYPE_INT_RGB); 26 | 27 | ColorConvertOp op = new ColorConvertOp(null); 28 | op.filter(edges, rgbImage); 29 | ImageIO.write(rgbImage, "JPEG", output); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /algorithms/MedianFIlter/.idea/description.html: -------------------------------------------------------------------------------- 1 | Simple Java application that includes a class with main() method -------------------------------------------------------------------------------- /algorithms/MedianFIlter/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /algorithms/MedianFIlter/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithms/MedianFIlter/.idea/project-template.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /algorithms/MedianFIlter/Images/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/MedianFIlter/Images/output.jpg -------------------------------------------------------------------------------- /algorithms/MedianFIlter/Images/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/MedianFIlter/Images/photo.jpg -------------------------------------------------------------------------------- /algorithms/MedianFIlter/MedianFIlter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /algorithms/MedianFIlter/out/production/MedianFIlter/com/company/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/MedianFIlter/out/production/MedianFIlter/com/company/Main.class -------------------------------------------------------------------------------- /algorithms/MedianFIlter/src/com/company/Main.java: -------------------------------------------------------------------------------- 1 | package com.company; 2 | import java.awt.Color; 3 | import java.awt.image.BufferedImage; 4 | import java.io.*; 5 | import java.util.Arrays; 6 | import javax.imageio.*; 7 | 8 | public class Main { 9 | 10 | public static void main(String[] args) throws Throwable { 11 | //File f=new File("/photo.jpg"); //Input Photo File 12 | Color[] pixel=new Color[9]; 13 | int[] R=new int[9]; 14 | int[] B=new int[9]; 15 | int[] G=new int[9]; 16 | File output=new File("Images/output.jpg"); 17 | 18 | BufferedImage img= ImageIO.read(new File("Images/photo.jpg")); 19 | for(int i=1;i 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /algorithms/MirrorFIlter/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithms/MirrorFIlter/Images/output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/MirrorFIlter/Images/output.jpg -------------------------------------------------------------------------------- /algorithms/MirrorFIlter/Images/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/MirrorFIlter/Images/photo.jpg -------------------------------------------------------------------------------- /algorithms/MirrorFIlter/MirrorFIlter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /algorithms/MirrorFIlter/out/production/MirrorFIlter/MirrorFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/algorithms/MirrorFIlter/out/production/MirrorFIlter/MirrorFilter.class -------------------------------------------------------------------------------- /algorithms/MirrorFIlter/src/MirrorFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by enzoftware on 5/29/17. 3 | */ 4 | 5 | import java.awt.*; 6 | import java.awt.image.BufferedImage; 7 | import java.io.File; 8 | import javax.imageio.*; 9 | 10 | public class MirrorFilter { 11 | 12 | public static void main(String[] args) throws Throwable { 13 | int r,g,b; 14 | int r1,g1,b1; 15 | Color color; 16 | Color color1; 17 | File output=new File("Images/output.jpg"); //Input Photo File 18 | 19 | BufferedImage photo= ImageIO.read(new File("Images/photo.jpg")); 20 | int width = photo.getWidth()-1; 21 | for(int i=0;i< ( photo.getWidth() ) / 2;i++){ 22 | for(int j=0;j 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /android/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.3" 6 | defaultConfig { 7 | applicationId "com.imageprocessing.enzoftware.imageprocessingapp" 8 | minSdkVersion 21 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.3.1' 28 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 29 | compile 'com.wang.avi:library:2.1.3' 30 | testCompile 'junit:junit:4.12' 31 | 32 | } 33 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/enzoftware/Android/Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/imageprocessing/enzoftware/imageprocessingapp/Canny.java: -------------------------------------------------------------------------------- 1 | package com.imageprocessing.enzoftware.imageprocessingapp; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Color; 5 | import android.os.Environment; 6 | import android.util.Log; 7 | 8 | import java.io.File; 9 | import java.io.FileOutputStream; 10 | 11 | public class Canny { 12 | public Bitmap process(Bitmap Imagem){ 13 | int width = Imagem.getWidth(); 14 | int height = Imagem.getHeight(); 15 | 16 | Bitmap n = Bitmap.createBitmap(Imagem,0,0,width,height); 17 | 18 | int[][] allPixR = new int[width][height]; 19 | int[][] allPixG = new int[width][height]; 20 | int[][] allPixB = new int[width][height]; 21 | 22 | for ( int i = 0; i < Imagem.getWidth(); i++ ) 23 | { 24 | for ( int j = 0; j < Imagem.getHeight(); j++ ) 25 | { 26 | int pixi = Imagem.getPixel(i,j); 27 | allPixR[i][ j] = Color.red(pixi); 28 | allPixG[i][ j] = Color.green(pixi); 29 | allPixB[i][ j] = Color.blue(pixi); 30 | } 31 | } 32 | for ( int i = 2; i < width - 2; i++ ) 33 | { 34 | for ( int j = 2; j < height - 2; j++ ) 35 | { 36 | int red = ( 37 | ( ( allPixR [i - 2][ j - 2] ) + ( allPixR [i - 1][ j - 2] ) * 4 + ( allPixR [i][ j - 2] ) * 7 + ( allPixR [i + 1][ j - 2] ) * 4 + ( allPixR [i + 2][ j - 2] ) 38 | + ( allPixR [i - 2][ j - 1] ) * 4 + ( allPixR [i - 1][ j - 1] ) * 16 + ( allPixR [i][ j - 1] ) * 26 + ( allPixR [i + 1][ j - 1] ) * 16 + ( allPixR [i + 2][ j - 1] ) * 4 39 | + ( allPixR [i - 2][ j] ) * 7 + ( allPixR [i - 1][ j] ) * 26 + ( allPixR [i][ j] ) * 41 + ( allPixR [i + 1][ j] ) * 26 + ( allPixR [i + 2][ j] ) * 7 40 | + ( allPixR [i - 2][ j + 1] ) * 4 + ( allPixR [i - 1][ j + 1] ) * 16 + ( allPixR [i][ j + 1] ) * 26 + ( allPixR [i + 1][ j + 1] ) * 16 + ( allPixR [i + 2][ j + 1] ) * 4 41 | + ( allPixR [i - 2][ j + 2] ) + ( allPixR [i - 1][ j + 2] ) * 4 + ( allPixR [i][ j + 2] ) * 7 + ( allPixR [i + 1][ j + 2] ) * 4 + ( allPixR [i + 2][ j + 2] ) ) / 273 42 | ); 43 | 44 | int green = ( 45 | ( ( allPixG[i - 2][ j - 2] ) + ( allPixG[i - 1][ j - 2] ) * 4 + ( allPixG[i][ j - 2] ) * 7 + ( allPixG[i + 1][ j - 2] ) * 4 + ( allPixG[i + 2][ j - 2] ) 46 | + ( allPixG[i - 2][ j - 1] ) * 4 + ( allPixG[i - 1][ j - 1] ) * 16 + ( allPixG[i][ j - 1] ) * 26 + ( allPixG[i + 1][ j - 1] ) * 16 + ( allPixG[i + 2][ j - 1] ) * 4 47 | + ( allPixG[i - 2][ j] ) * 7 + ( allPixG[i - 1][ j] ) * 26 + ( allPixG[i][ j] ) * 41 + ( allPixG[i + 1][ j] ) * 26 + ( allPixG[i + 2][ j] ) * 7 48 | + ( allPixG[i - 2][ j + 1] ) * 4 + ( allPixG[i - 1][ j + 1] ) * 16 + ( allPixG[i][ j + 1] ) * 26 + ( allPixG[i + 1][ j + 1] ) * 16 + ( allPixG[i + 2][ j + 1] ) * 4 49 | + ( allPixG[i - 2][ j + 2] ) + ( allPixG[i - 1][ j + 2] ) * 4 + ( allPixG[i][ j + 2] ) * 7 + ( allPixG[i + 1][ j + 2] ) * 4 + ( allPixG[i + 2][ j + 2] ) ) / 273 50 | ); 51 | 52 | int blue = ( 53 | ( ( allPixB[i - 2][ j - 2] ) + ( allPixB[i - 1][ j - 2] ) * 4 + ( allPixB[i][ j - 2] ) * 7 + ( allPixB[i + 1][ j - 2] ) * 4 + ( allPixB[i + 2][ j - 2] ) 54 | + ( allPixB[i - 2][ j - 1] ) * 4 + ( allPixB[i - 1][ j - 1] ) * 16 + ( allPixB[i][ j - 1] ) * 26 + ( allPixB[i + 1][ j - 1] ) * 16 + ( allPixB[i + 2][ j - 1] ) * 4 55 | + ( allPixB[i - 2][ j] ) * 7 + ( allPixB[i - 1][ j] ) * 26 + ( allPixB[i][ j] ) * 41 + ( allPixB[i + 1][ j] ) * 26 + ( allPixB[i + 2][ j] ) * 7 56 | + ( allPixB[i - 2][ j + 1] ) * 4 + ( allPixB[i - 1][ j + 1] ) * 16 + ( allPixB[i][ j + 1] ) * 26 + ( allPixB[i + 1][ j + 1] ) * 16 + ( allPixB[i + 2][ j + 1] ) * 4 57 | + ( allPixB[i - 2][ j + 2] ) + ( allPixB[i - 1][ j + 2] ) * 4 + ( allPixB[i][ j + 2] ) * 7 + ( allPixB[i + 1][ j + 2] ) * 4 + ( allPixB[i + 2][ j + 2] ) ) / 273 58 | ); 59 | n.setPixel (i, j, Color.rgb (red, green, blue)); 60 | } 61 | } 62 | 63 | 64 | int[][] allPixRn = new int[width][height]; 65 | int[][] allPixGn = new int[width][height]; 66 | int[][] allPixBn = new int[width][height]; 67 | 68 | for ( int i = 0; i < width; i++ ) 69 | { 70 | for ( int j = 0; j < height; j++ ) 71 | { 72 | int pixi2 = n.getPixel(i,j); 73 | allPixRn[i][ j] = Color.red(pixi2); 74 | allPixGn[i][ j] =Color.green(pixi2); 75 | allPixBn[i][ j] =Color.blue(pixi2); 76 | } 77 | } 78 | 79 | 80 | int[][] gx = new int[][] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }; 81 | int[][] gy = new int[][] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } }; 82 | int new_rx = 0, new_ry = 0; 83 | int new_gx = 0, new_gy = 0; 84 | int new_bx = 0, new_by = 0; 85 | int rc, gc, bc; 86 | int gradR, gradG, gradB; 87 | 88 | int[][] graidientR = new int [width][ height]; 89 | int[][] graidientG = new int [width][ height]; 90 | int[][] graidientB = new int [width][ height]; 91 | 92 | int atanR,atanG,atanB; 93 | 94 | int[][] tanR = new int[width][ height]; 95 | int[][] tanG = new int[width][ height]; 96 | int[][] tanB = new int[width][ height]; 97 | 98 | 99 | for ( int i = 1; i < Imagem.getWidth() - 1; i++ ) 100 | { 101 | for ( int j = 1; j < Imagem.getHeight() - 1; j++ ) 102 | { 103 | 104 | new_rx = 0; 105 | new_ry = 0; 106 | new_gx = 0; 107 | new_gy = 0; 108 | new_bx = 0; 109 | new_by = 0; 110 | rc = 0; 111 | gc = 0; 112 | bc = 0; 113 | 114 | for ( int wi = -1; wi < 2; wi++ ) 115 | { 116 | for ( int hw = -1; hw < 2; hw++ ) 117 | { 118 | rc = allPixRn[i + hw ][j + wi]; 119 | new_rx += gx[wi + 1][ hw + 1] * rc; 120 | new_ry += gy[wi + 1][ hw + 1] * rc; 121 | 122 | gc = allPixGn[i + hw][ j + wi]; 123 | new_gx += gx[wi + 1][ hw + 1] * gc; 124 | new_gy += gy[wi + 1][ hw + 1] * gc; 125 | 126 | bc = allPixBn[i + hw][ j + wi]; 127 | new_bx += gx[wi + 1][ hw + 1] * bc; 128 | new_by += gy[wi + 1][ hw + 1] * bc; 129 | } 130 | } 131 | 132 | gradR = (int)Math.sqrt (( new_rx * new_rx ) + ( new_ry * new_ry )); 133 | graidientR [i][j]= gradR; 134 | 135 | gradG = (int)Math.sqrt (( new_gx * new_gx ) + ( new_gy * new_gy )); 136 | graidientG [i][j]= gradG; 137 | 138 | gradB = (int)Math.sqrt (( new_bx * new_gx ) + ( new_by * new_by )); 139 | graidientB [i][j]= gradB; 140 | 141 | 142 | atanR= (int)( ( Math.atan ((double)new_ry / new_rx) ) * ( 180 / Math.PI ) ); 143 | if ( (atanR > 0 && atanR < 22.5) || (atanR > 157.5 && atanR < 180) ) 144 | { 145 | atanR = 0; 146 | } 147 | else if (atanR > 22.5 && atanR < 67.5){ 148 | atanR = 45; 149 | } 150 | else if (atanR > 67.5 && atanR < 112.5){ 151 | atanR = 90; 152 | } 153 | else if (atanR > 112.5 && atanR < 157.5) { 154 | atanR = 135; 155 | } 156 | 157 | if ( atanR == 0 ) 158 | { 159 | tanR[i][ j] = 0; 160 | } 161 | else if ( atanR == 45 ) 162 | { 163 | tanR[i][ j] = 1; 164 | } 165 | else if ( atanR == 90 ) 166 | { 167 | tanR[i][ j] = 2; 168 | } 169 | else if ( atanR == 135 ) 170 | { 171 | tanR[i][ j] = 3; 172 | } 173 | 174 | 175 | atanG = (int)( ( Math.atan ((double)new_gy / new_gx) ) * ( 180 / Math.PI ) ); 176 | if ( ( atanG > 0 && atanG < 22.5 ) || ( atanG > 157.5 && atanG < 180 ) ) 177 | { 178 | atanG = 0; 179 | } 180 | else if ( atanG > 22.5 && atanG < 67.5 ) 181 | { 182 | atanG = 45; 183 | } 184 | else if ( atanG > 67.5 && atanG < 112.5 ) 185 | { 186 | atanG = 90; 187 | } 188 | else if ( atanG > 112.5 && atanG < 157.5 ) 189 | { 190 | atanG = 135; 191 | } 192 | 193 | 194 | if (atanG == 0){ 195 | tanG[i][ j] = 0; 196 | } 197 | else if (atanG == 45) { 198 | tanG[i][ j] = 1; 199 | } 200 | else if ( atanG == 90 ) 201 | { 202 | tanG[i][ j] = 2; 203 | } 204 | else if ( atanG == 135 ) 205 | { 206 | tanG[i][ j] = 3; 207 | } 208 | 209 | 210 | atanB = (int)( ( Math.atan ((double)new_by / new_bx) ) * ( 180 / Math.PI ) ); 211 | if ( ( atanB > 0 && atanB < 22.5 ) || ( atanB > 157.5 && atanB < 180 ) ) 212 | { 213 | atanB = 0; 214 | } 215 | else if ( atanB > 22.5 && atanB < 67.5 ) 216 | { 217 | atanB = 45; 218 | } 219 | else if ( atanB > 67.5 && atanB < 112.5 ) 220 | { 221 | atanB = 90; 222 | } 223 | else if ( atanB > 112.5 && atanB < 157.5 ) 224 | { 225 | atanB = 135; 226 | } 227 | 228 | if ( atanB == 0 ) 229 | { 230 | tanB[i][ j] = 0; 231 | } 232 | else if ( atanB == 45 ) 233 | { 234 | tanB[i][ j] = 1; 235 | } 236 | else if ( atanB == 90 ) 237 | { 238 | tanB[i][ j] = 2; 239 | } 240 | else if ( atanB == 135 ) 241 | { 242 | tanB[i][ j] = 3; 243 | } 244 | } 245 | } 246 | 247 | int[][] allPixRs = new int[width][ height]; 248 | int[][] allPixGs = new int[width][ height]; 249 | int[][] allPixBs = new int[width][ height]; 250 | 251 | for ( int i = 2; i < width-2; i++ ) 252 | { 253 | for ( int j = 2; j < height-2; j++ ) 254 | { 255 | 256 | if ( tanR[i][ j] == 0 ) 257 | { 258 | if ( graidientR[i - 1][ j] < graidientR[i][ j] && graidientR[i + 1][ j] < graidientR[i][ j] ) 259 | { 260 | allPixRs[i][ j] = graidientR[i][ j]; 261 | } 262 | else { 263 | allPixRs[i][j] = 0; 264 | } 265 | } 266 | if ( tanR[i][ j] == 1 ) 267 | { 268 | if ( graidientR[i - 1][ j + 1] < graidientR[i][ j] && graidientR[i + 1][ j - 1] < graidientR[i][ j] ) 269 | { 270 | allPixRs[i][ j] = graidientR[i][ j]; 271 | } 272 | else 273 | { 274 | allPixRs[i][ j] = 0; 275 | } 276 | } 277 | if ( tanR[i][ j] == 2 ) 278 | { 279 | if ( graidientR[i][ j - 1] < graidientR[i][ j] && graidientR[i][ j + 1] < graidientR[i][ j] ) 280 | { 281 | allPixRs[i][ j] = graidientR[i][ j]; 282 | } 283 | else 284 | { 285 | allPixRs[i][ j] = 0; 286 | } 287 | } 288 | if ( tanR[i][ j] == 3 ) 289 | { 290 | if ( graidientR[i - 1][ j - 1] < graidientR[i][ j] && graidientR[i + 1][ j + 1] < graidientR[i][ j] ) 291 | { 292 | allPixRs[i][ j] = graidientR[i][ j]; 293 | } 294 | else 295 | { 296 | allPixRs[i][ j] = 0; 297 | } 298 | } 299 | 300 | if ( tanG[i][ j] == 0 ) 301 | { 302 | if ( graidientG[i - 1][ j] < graidientG[i][ j] && graidientG[i + 1][ j] < graidientG[i][ j] ) 303 | { 304 | allPixGs[i][ j] = graidientG[i][ j]; 305 | } 306 | else 307 | { 308 | allPixGs[i][ j] = 0; 309 | } 310 | } 311 | if ( tanG[i][ j] == 1 ) 312 | { 313 | if ( graidientG[i - 1][ j + 1] < graidientG[i][ j] && graidientG[i + 1][ j - 1] < graidientG[i][ j] ) 314 | { 315 | allPixGs[i][ j] = graidientG[i][ j]; 316 | } 317 | else 318 | { 319 | allPixGs[i][ j] = 0; 320 | } 321 | } 322 | if ( tanG[i][ j] == 2 ) 323 | { 324 | if ( graidientG[i][ j - 1] < graidientG[i][ j] && graidientG[i][ j + 1] < graidientG[i][ j] ) 325 | { 326 | allPixGs[i][ j] = graidientG[i][ j]; 327 | } 328 | else 329 | { 330 | allPixGs[i][ j] = 0; 331 | } 332 | } 333 | if ( tanG[i][ j] == 3 ) 334 | { 335 | if ( graidientG[i - 1][ j - 1] < graidientG[i][ j] && graidientG[i + 1][ j + 1] < graidientG[i][ j] ) 336 | { 337 | allPixGs[i][ j] = graidientG[i][ j]; 338 | } 339 | else 340 | { 341 | allPixGs[i][ j] = 0; 342 | } 343 | } 344 | 345 | if ( tanB[i][ j] == 0 ) 346 | { 347 | if ( graidientB[i - 1][ j] < graidientB[i][ j] && graidientB[i + 1][ j] < graidientB[i][ j] ) 348 | { 349 | allPixBs[i][ j] = graidientB[i][ j]; 350 | } 351 | else 352 | { 353 | allPixBs[i][ j] = 0; 354 | } 355 | } 356 | if ( tanB[i][ j] == 1 ) 357 | { 358 | if ( graidientB[i - 1][ j + 1] < graidientB[i][ j] && graidientB[i + 1][ j - 1] < graidientB[i][ j] ) 359 | { 360 | allPixBs[i][ j] = graidientB[i][ j]; 361 | } 362 | else 363 | { 364 | allPixBs[i][ j] = 0; 365 | } 366 | } 367 | if ( tanB[i][ j] == 2 ) 368 | { 369 | if ( graidientB[i][ j - 1] < graidientB[i][ j] && graidientB[i][ j + 1] < graidientB[i][ j] ) 370 | { 371 | allPixBs[i][ j] = graidientB[i][ j]; 372 | } 373 | else 374 | { 375 | allPixBs[i][ j] = 0; 376 | } 377 | } 378 | if ( tanB[i][ j] == 3 ) 379 | { 380 | if ( graidientB[i - 1][ j - 1] < graidientB[i][ j] && graidientB[i + 1][ j + 1] < graidientB[i][ j] ) 381 | { 382 | allPixBs[i][ j] = graidientB[i][ j]; 383 | } 384 | else 385 | { 386 | allPixBs[i][ j] = 0; 387 | } 388 | } 389 | } 390 | } 391 | 392 | int threshold = 50; 393 | int[][] allPixRf = new int[width][ height]; 394 | int[][] allPixGf = new int[width][ height]; 395 | int[][] allPixBf = new int[width][ height]; 396 | 397 | Bitmap bb = Bitmap.createBitmap(Imagem,0,0,width,height); 398 | 399 | for (int i = 2; i threshold ) 403 | { 404 | allPixRf[i][ j] = 1; 405 | } 406 | else { 407 | allPixRf[i][ j] = 0; 408 | } 409 | 410 | if ( allPixGs[i][ j] > threshold ) 411 | { 412 | allPixGf[i][ j] = 1; 413 | } 414 | else 415 | { 416 | allPixGf[i][ j] = 0; 417 | } 418 | 419 | if ( allPixBs[i][ j] > threshold ) 420 | { 421 | allPixBf[i][ j] = 1; 422 | } 423 | else 424 | { 425 | allPixBf[i][ j] = 0; 426 | } 427 | 428 | 429 | 430 | if ( allPixRf[i][ j] == 1 || allPixGf[i][ j] == 1 || allPixBf[i][ j] == 1 ) 431 | { 432 | bb.setPixel (i, j, Color.rgb(255,255,255)); 433 | } 434 | else 435 | bb.setPixel (i, j, Color.rgb(0,0,0)); 436 | } 437 | } 438 | saveImage(bb,"fotazo"); 439 | Imagem = Bitmap.createBitmap(bb,0,0,bb.getWidth(),bb.getHeight()); 440 | return Imagem; 441 | } 442 | 443 | private void saveImage(Bitmap finalBitmap, String image_name) { 444 | String root = Environment.getExternalStorageDirectory().toString(); 445 | File myDir = new File(root); 446 | myDir.mkdirs(); 447 | String fname = "Image-" + image_name + ".jpg"; 448 | File file = new File(myDir, fname); 449 | if (file.exists()) file.delete(); 450 | Log.i("LOAD", root + fname); 451 | try { 452 | FileOutputStream out = new FileOutputStream(file); 453 | finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); 454 | out.flush(); 455 | out.close(); 456 | } catch (Exception e) { 457 | e.printStackTrace(); 458 | } 459 | } 460 | 461 | } 462 | 463 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/imageprocessing/enzoftware/imageprocessingapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.imageprocessing.enzoftware.imageprocessingapp; 2 | 3 | import android.content.Intent; 4 | import android.database.Cursor; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.graphics.Color; 8 | import android.net.Uri; 9 | import android.os.Environment; 10 | import android.provider.MediaStore; 11 | import android.support.v7.app.AppCompatActivity; 12 | import android.os.Bundle; 13 | import android.util.Log; 14 | import android.view.View; 15 | import android.widget.Button; 16 | import android.widget.ImageButton; 17 | import android.widget.ProgressBar; 18 | import android.widget.Toast; 19 | 20 | import com.wang.avi.AVLoadingIndicatorView; 21 | 22 | import java.io.File; 23 | import java.io.FileOutputStream; 24 | import java.util.Arrays; 25 | 26 | 27 | public class MainActivity extends AppCompatActivity { 28 | AVLoadingIndicatorView avi; 29 | ImageButton picker, output; 30 | Button medianFilter, mirrorFilter, cannyFilter; 31 | ProgressBar scrollView; 32 | private static int RESULT_LOAD_IMG = 1; 33 | String impDeclarableString; 34 | public Bitmap bmp = null; 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_main); 40 | picker = (ImageButton) findViewById(R.id.imageButton); 41 | medianFilter = (Button) findViewById(R.id.medianFilter); 42 | output = (ImageButton) findViewById(R.id.outputImage); 43 | mirrorFilter = (Button) findViewById(R.id.mirrorFilter); 44 | scrollView = (ProgressBar) findViewById(R.id.scrollView); 45 | cannyFilter = (Button) findViewById(R.id.cannyFilter); 46 | 47 | 48 | picker.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | 52 | loadImageryGallery(); 53 | 54 | } 55 | }); 56 | 57 | medianFilter.setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | if (bmp != null) { 61 | output.setImageBitmap(medianFilterAlgorithm(bmp)); 62 | saveImage(bmp, "fotazo"); 63 | } else { 64 | Toast.makeText(getApplicationContext(), "No has seleccionado ninguna foto", Toast.LENGTH_LONG) 65 | .show(); 66 | } 67 | } 68 | }); 69 | 70 | 71 | cannyFilter.setOnClickListener(new View.OnClickListener() { 72 | @Override 73 | public void onClick(View v) { 74 | if (bmp != null) { 75 | cannyFilterAlg(bmp); 76 | } else { 77 | Toast.makeText(getApplicationContext(), "No has seleccionado ninguna foto", Toast.LENGTH_LONG) 78 | .show(); 79 | } 80 | } 81 | }); 82 | 83 | 84 | mirrorFilter.setOnClickListener(new View.OnClickListener() { 85 | @Override 86 | public void onClick(View v) { 87 | 88 | 89 | if (bmp != null) { 90 | output.setImageBitmap(mirrorFilterAlgorithm(bmp)); 91 | saveImage(bmp, "fotazo"); 92 | } else { 93 | Toast.makeText(getApplicationContext(), "No has seleccionado ninguna foto", Toast.LENGTH_LONG) 94 | .show(); 95 | } 96 | } 97 | }); 98 | 99 | } 100 | 101 | 102 | 103 | public void loadImageryGallery() { 104 | Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 105 | startActivityForResult(galleryIntent, RESULT_LOAD_IMG); 106 | } 107 | 108 | @Override 109 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 110 | super.onActivityResult(requestCode, resultCode, data); 111 | try { 112 | if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) { 113 | Uri selectedImage = data.getData(); 114 | String[] filePathColumn = {MediaStore.Images.Media.DATA}; 115 | Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); 116 | cursor.moveToFirst(); 117 | int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 118 | impDeclarableString = cursor.getString(columnIndex); 119 | cursor.close(); 120 | Bitmap copy = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(impDeclarableString), 121 | 714, 122 | 438, 123 | false); 124 | picker.setImageBitmap(copy); 125 | Bitmap b = BitmapFactory.decodeFile(impDeclarableString); 126 | final Bitmap resizable = Bitmap.createScaledBitmap(b, 714, 438, false); 127 | bmp = Bitmap.createScaledBitmap(resizable, 714, 438, false); 128 | 129 | } 130 | } catch (Exception e) { 131 | Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG) 132 | .show(); 133 | } 134 | 135 | } 136 | 137 | 138 | private void saveImage(Bitmap finalBitmap, String image_name) { 139 | String root = Environment.getExternalStorageDirectory().toString(); 140 | File myDir = new File(root); 141 | myDir.mkdirs(); 142 | String fname = "Image-" + image_name + ".jpg"; 143 | File file = new File(myDir, fname); 144 | if (file.exists()) file.delete(); 145 | Log.i("LOAD", root + fname); 146 | try { 147 | FileOutputStream out = new FileOutputStream(file); 148 | finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); 149 | out.flush(); 150 | out.close(); 151 | } catch (Exception e) { 152 | e.printStackTrace(); 153 | } 154 | } 155 | 156 | private Bitmap medianFilterAlgorithm(Bitmap bitmap) { 157 | int[] pixel = new int[9]; 158 | int[] R = new int[9]; 159 | int[] G = new int[9]; 160 | int[] B = new int[9]; 161 | Bitmap out = bitmap; 162 | for (int i = 1; i < bitmap.getWidth() - 1; i++) { 163 | for (int j = 1; j < bitmap.getHeight() - 1; j++) { 164 | 165 | pixel[0] = bitmap.getPixel(i - 1, j - 1); 166 | pixel[1] = bitmap.getPixel(i - 1, j); 167 | pixel[2] = bitmap.getPixel(i - 1, j + 1); 168 | pixel[3] = bitmap.getPixel(i, j + 1); 169 | pixel[4] = bitmap.getPixel(i + 1, j + 1); 170 | pixel[5] = bitmap.getPixel(i + 1, j); 171 | pixel[6] = bitmap.getPixel(i + 1, j - 1); 172 | pixel[7] = bitmap.getPixel(i, j - 1); 173 | pixel[8] = bitmap.getPixel(i, j); 174 | 175 | for (int k = 0; k < 9; k++) { 176 | R[k] = Color.red(pixel[k]); 177 | G[k] = Color.green(pixel[k]); 178 | B[k] = Color.blue(pixel[k]); 179 | } 180 | 181 | Arrays.sort(R); 182 | Arrays.sort(G); 183 | Arrays.sort(B); 184 | out.setPixel(i, j, Color.rgb(R[4], G[4], B[4])); 185 | } 186 | } 187 | return out; 188 | } 189 | 190 | private Bitmap mirrorFilterAlgorithm(Bitmap photo) { 191 | int r, g, b; 192 | int r1, g1, b1; 193 | int width = photo.getWidth() - 1; 194 | int color; 195 | int color1; 196 | Bitmap out = photo; 197 | for (int i = 0; i < (photo.getWidth()) / 2; i++) { 198 | for (int j = 0; j < photo.getHeight(); j++) { 199 | 200 | color1 = photo.getPixel(i, j); 201 | color = photo.getPixel(width, j); 202 | 203 | r = Color.red(color); 204 | g = Color.green(color); 205 | b = Color.blue(color); 206 | 207 | r1 = Color.red(color1); 208 | g1 = Color.green(color1); 209 | b1 = Color.blue(color1); 210 | 211 | out.setPixel(i, j, Color.rgb(r, g, b)); 212 | out.setPixel(width, j, Color.rgb(r1, g1, b1)); 213 | } 214 | width--; 215 | } 216 | Log.d("FUNCIONA", "FUNCIONA"); 217 | return out; 218 | } 219 | 220 | 221 | private Bitmap cannyFilterAlg(Bitmap Image) { 222 | Canny myCanny = new Canny(); 223 | output.setImageBitmap(myCanny.process(Image)); 224 | return Image; 225 | } 226 | 227 | 228 | } 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/android/app/src/main/res/drawable/love.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/metalprocessing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/android/app/src/main/res/drawable/metalprocessing.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/p_icon_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzoftware/images-processing/e2343ba6a0375f492b0f527c2c69206c856d7953/android/app/src/main/res/drawable/p_icon_01.png -------------------------------------------------------------------------------- /android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 22 | 23 | 30 | 31 | 32 | 36 | 37 |