├── Documenti ├── FMECA.xlsx ├── Paper.pdf └── thesis.pdf ├── README.md ├── banding ├── banding-readme ├── banding.png └── banding1.jpg ├── black.py ├── blurred.py ├── brightness.py ├── broken1.png ├── broken7.png ├── broken8.jpg ├── chromaticaberration.py ├── condensation.png ├── condensation ├── condensation-readme ├── condensation1.png ├── condensation2.png └── condensation3.png ├── deadpixel-fixedposition.py ├── deadpixel200-fixedposition.py ├── deadpixel50-fixedposition.py ├── dirtygrey3.png ├── dirtyonglass.png ├── failure_example ├── bandingfail.jpg ├── black.jpg ├── blurredimage.jpg ├── brightness15.jpg ├── brightness25.jpg ├── broken1-fail.jpg ├── broken1-fail2.jpg ├── chromabefail.jpg ├── chromabefail2.jpg ├── condens.jpg ├── dead1000pixel.jpg ├── dead200pixel.jpg ├── dead50pixel.jpg ├── deadpixel-10lines-5H5V.jpg ├── deadpixel-1vertical-line.jpg ├── deadpixel-3lines-2H1V.jpg ├── deadpixel-5lines-3H2V.jpg ├── deadpixel-carregg-obstacle.jpg ├── deadpixel-carreggiata.jpg ├── deadpixel1.jpg ├── dirtyglass.jpg ├── dirtyglass2.jpg ├── icebrigfail.jpg ├── icebrigfail2.jpg ├── nobayerfilterimage.jpg ├── nodemosfail.jpg ├── noiseredu.jpg ├── noiseredu1.jpg ├── originale.jpg ├── rainglassfail.jpg ├── sharpnesscorr.jpg └── white.jpg ├── ice ├── ice-readme ├── ice1.png ├── ice2.png ├── ice3.png └── ice4.png ├── nobayesfilter-greyscale.py ├── nobayesfilter-greyscale2.py ├── nodemos.py ├── noise.py ├── overlay_images.py ├── overlay_images2.py ├── rain ├── rain-readme ├── rain1.png ├── rain2.png ├── rain3.png ├── rain4.png └── rain5.png ├── rainglass.png ├── sharpness.py ├── sim1.jpg └── white.py /Documenti/FMECA.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/Documenti/FMECA.xlsx -------------------------------------------------------------------------------- /Documenti/Paper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/Documenti/Paper.pdf -------------------------------------------------------------------------------- /Documenti/thesis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/Documenti/thesis.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Image Failures 2 | 3 | This repository contains codes that are used to simulate failures that can occur in a camera during the acquisition/processing phase. 4 | 5 | The codes were found and modified, so as to be optimal for the work that had to be done. 6 | 7 | ### How to cite our work: 8 | 9 | Francesco Secci, Andrea Ceccarelli. "On failures of RGB cameras and their effects in autonomous driving applications." In: The 31st International Symposium on Software Reliability Engineering (ISSRE) 2020. 10 | 11 | 12 | Andrea Ceccarelli, Francesco Secci: "RGB cameras failures and their effects in autonomous driving applications", In press at IEEE Transactions on Dependable and Secure Computing. 13 | 14 | ## How is this repo organized 15 | There are various python files, and some images. 16 | In general: 17 | - sim1.jpg is the target image, on which failures are applied 18 | - each python file allows injecting a different failure on sim1.jpg. Usually, the name of the file itself indicates the failures: 19 | - some failures (banding, ice, condensation, dirt, rain, broken lens) requires a second image, that is overlapped on sim1.jpg. In these cases, some possible images are available in the repository (e.g., banding.png, ice1.png). Obviously, many others can be used. The python file to consider in this case is overlay_images.py. 20 | - other failures may have configuration parameters, you can play with them. It is easy to spot the required configuration just looking at the code and the comments. 21 | 22 | ## Few things about the code used 23 | 24 | For the conversion from 'PIL.JpegImagePlugin.JpegImageFile' (or 'PIL.Image.Image') to 'numpy.ndarray' you can use the command: 25 | ```python 26 | img1 = np.array(picture) # now img1 is a object 27 | ``` 28 | 29 | For the opposite conversion (from 'numpy.ndarray' to 'PIL.Image.Image') you can use the command: 30 | ```python 31 | img1 = Image.fromarray(blur, 'RGB') # now img1 is a object 32 | ``` 33 | 34 | If the image is opened using the cv2.imread() method (OpenCV) and converted into a 'PIL.Image' object, saving it, it will have wrong colors: the R and B channels will be inverted, therefore, in the codes in the repository, the command below has often been used: 35 | ```python 36 | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR to RGB 37 | ``` 38 | 39 |

40 | ## Types of weather available in the simulator: 41 | 42 | - [ ] 0 - Default 43 | - [x] 1 - ClearNoon 44 | - [ ] 2 - CloudyNoon 45 | - [ ] 3 - WetNoon 46 | - [x] 4 - WetCloudyNoon 47 | - [ ] 5 - MidRainyNoon 48 | - [ ] 6 - HardRainNoon 49 | - [ ] 7 - SoftRainNoon 50 | - [ ] 8 - ClearSunset 51 | - [ ] 9 - CloudySunset 52 | - [ ] 10 - WetSunset 53 | - [ ] 11 - WetCloudySunset 54 | - [ ] 12 - MidRainSunset 55 | - [x] 13 - HardRainSunset 56 | - [ ] 14 - SoftRainSunset 57 | 58 | The marked weather are those used in the work done. 59 | 60 |

61 | ## Results obtained with the injection of failures in CARLA simulator 62 | 63 | Success Rate of Golden Run: 64 | 65 | | \/\\\/\\\/\\\/\\\/\\ | FullTown02 | StraightTown02 | TurnTown02 | 66 | | ------------- | ------------- | ------------- | ------------- | 67 | | GoldenRun | 90 | 100 | 100 | 68 | 69 | 70 | Success rates of injected failures: 71 | 72 | | Failure name | FullTown02 | StraightTown02 | TurnTown02 | 73 | | ------------- | ------------- | ------------- | ------------- | 74 | | NONOISE1 | 76 | 100 | 98 | 75 | | NONOISE2 | 16 | 90 | 40 | 76 | | BLUR | 6 | 82 | 40 | 77 | | BRIGH1 | 76 | 98 | 96 | 78 | | BRIGH2 | 18 | 78 | 48 | 79 | | WHI | 0 | 10 | 0 | 80 | | BLA | 0 | 12 | 0 | 81 | | BRLE1 | 0 | 22 | 8 | 82 | | BRLE2 | 38 | 96 | 74 | 83 | | NBAYF | 74 | 98 | 98 | 84 | | NOSHARP | 80 | 100 | 86 | 85 | | NOCHROMAB-nb | 52 | 96 | 76 | 86 | | NOCHROMAB-b | 32 | 92 | 60 | 87 | | ICE1 | 60 | 98 | 90 | 88 | | ICE2 | 2 | 86 | 8 | 89 | | DIRTY1 | 76 | 100 | 98 | 90 | | DIRTY2 | 34 | 98 | 70 | 91 | | RAIN | 66 | 100 | 92 | 92 | | COND | 32 | 94 | 84 | 93 | | BAND | 90 | 100 | 96 | 94 | | NODEMOS | 78 | 98 | 88 | 95 | | DEAPIX1 | 90 | 98 | 100 | 96 | | DEAPIX50 | 80 | 98 | 98 | 97 | | DEAPIX200 | 74 | 100 | 100 | 98 | | DEAPIX1000 | 74 | 100 | 98 | 99 | | DEAPIX-vcl | 82 | 100 | 98 | 100 | | DEAPIX-3l | 68 | 100 | 92 | 101 | | DEAPIX-5l | 52 | 96 | 90 | 102 | | DEAPIX-10l | 70 | 94 | 98 | 103 | | DEAPIXl-r | 40 | 100 | 68 | 104 | | DEAPIX-ro | 36 | 100 | 70 | 105 | | Average Success Rate per Scenario (GoldenRun included) | 51.94 % | 88.56 % | 73.81 % | 106 | 107 |

108 | ## Examples of failures injected 109 | 110 | | | | | | 111 | |:--:|:--:|:--:|:--:| 112 | | GoldenRun | NONOISE1 | NONOISE2 | BLUR | 113 | | | | | | 114 | | WHI | BRIGH1 | BRIGH2 | BLA | 115 | | | | | | 116 | | BRLE1 | BRLE2 | NBAYF | NOSHARP | 117 | | | | | | 118 | | NOCHROMAB-nb | NOCHROMAB-b | ICE1 | ICE2 | 119 | | | | | | 120 | | DIRTY1 | DIRTY2 | RAIN | COND | 121 | | | | | | 122 | | BAND | NODEMOS | DEAPIX1 | DEAPIX50 | 123 | | | | | | 124 | | DEAPIX200 | DEAPIX1000 | DEAPIX-vcl | DEAPIX-3l | 125 | | | | | | 126 | | DEAPIX-5l | DEAPIX-10l | DEAPIX-r | DEAPIX-ro | 127 | 128 |

129 | ### A detailed description of this work can be found in: 130 | 131 | Francesco Secci, "On failures of RGB cameras and their effects in autonomous driving applications", Master Thesis at the University of Florence, Italy (in Italian only), July 2020. ([thesis](https://github.com/francescosecci/Python_Image_Failures/blob/master/Documenti/thesis.pdf)) 132 |

133 | Francesco Secci, Andrea Ceccarelli, "On failures of RGB cameras and their effects in autonomous driving applications", 31st International Symposium on Software Reliability Engineering (ISSRE 2020). ([paper](https://github.com/francescosecci/Python_Image_Failures/blob/master/Documenti/Paper.pdf)) 134 |

135 | 136 | Andrea Ceccarelli, Francesco Secci: "RGB cameras failures and their effects in autonomous driving applications", In press at IEEE Transactions on Dependable and Secure Computing. https://arxiv.org/abs/2008.05938 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /banding/banding-readme: -------------------------------------------------------------------------------- 1 | images to be superimposed for banding effects 2 | -------------------------------------------------------------------------------- /banding/banding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/banding/banding.png -------------------------------------------------------------------------------- /banding/banding1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/banding/banding1.jpg -------------------------------------------------------------------------------- /black.py: -------------------------------------------------------------------------------- 1 | #this just converts the input image sim1.jpg to an entirely black image 2 | from PIL import Image 3 | from matplotlib import pyplot as plt 4 | 5 | picture1 = Image.open("sim1.jpg") 6 | picture = Image.open("sim1.jpg") 7 | 8 | pixels = picture.load() 9 | width, height = picture.size 10 | 11 | for i in range(0,width): 12 | for j in range(0,height): 13 | pixels[i,j] = (0, 0, 0) 14 | 15 | #picture e picture1 --> 16 | 17 | #il codice sotto serve come presentazione per mostrare il fallimento 18 | plt.figure(num='Fallimento BLACK') 19 | plt.subplot(121),plt.imshow(picture1),plt.title('Originale') 20 | plt.xticks([]), plt.yticks([]) 21 | plt.subplot(122),plt.imshow(picture),plt.title('Black') 22 | plt.xticks([]), plt.yticks([]) 23 | plt.show() 24 | 25 | #ok 26 | -------------------------------------------------------------------------------- /blurred.py: -------------------------------------------------------------------------------- 1 | #add blur to the image sim1.jpg 2 | import cv2 3 | from matplotlib import pyplot as plt 4 | 5 | img = cv2.imread('sim1.jpg') 6 | 7 | blur = cv2.blur(img,(5,5)) #change values to increment/decrement blur. 0 is "no blur" 8 | 9 | #blur e img --> 10 | 11 | #il codice sotto serve come presentazione per mostrare il fallimento 12 | plt.figure(num='Fallimento BLURRED') 13 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 14 | plt.xticks([]), plt.yticks([]) 15 | plt.subplot(122),plt.imshow(blur),plt.title('Sfocata') 16 | plt.xticks([]), plt.yticks([]) 17 | plt.show() 18 | 19 | #ok 20 | -------------------------------------------------------------------------------- /brightness.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageEnhance 2 | from matplotlib import pyplot as plt 3 | 4 | ''' 5 | Brightness: This class can be used to control the 6 | brightness of an image. An enhancement 7 | factor of 0.0 gives a black image. 8 | A factor of 1.0 gives the original image. 9 | ''' 10 | 11 | 12 | img = Image.open("sim1.jpg") 13 | 14 | enhancer = ImageEnhance.Brightness(img) 15 | 16 | #An enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the original image. 17 | factor = 1 18 | img1 = enhancer.enhance(factor) 19 | 20 | #An enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the original image. 21 | factor = 3.5 22 | img2 = enhancer.enhance(factor) 23 | 24 | # img --> 25 | # img1 e img2 --> 26 | 27 | plt.figure(num='Fallimento BRIGHTNESS') 28 | plt.subplot(121),plt.imshow(img1),plt.title('Originale') 29 | plt.xticks([]), plt.yticks([]) 30 | plt.subplot(122),plt.imshow(img2),plt.title('Luminosità Aumentata') 31 | plt.xticks([]), plt.yticks([]) 32 | plt.show() 33 | 34 | #ok 35 | -------------------------------------------------------------------------------- /broken1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/broken1.png -------------------------------------------------------------------------------- /broken7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/broken7.png -------------------------------------------------------------------------------- /broken8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/broken8.jpg -------------------------------------------------------------------------------- /chromaticaberration.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Kromo V0.3 4 | === Author === 5 | Yoonsik Park 6 | park.yoonsik@icloud.com 7 | === Description === 8 | Use the command line interface to add chromatic abberation and 9 | lens blur to your images, or import some of the functions below. 10 | 11 | """ 12 | 13 | from PIL import Image 14 | import numpy as np 15 | import math 16 | from typing import List 17 | 18 | from matplotlib import pyplot as plt 19 | 20 | def cartesian_to_polar(data: np.ndarray) -> np.ndarray: 21 | """Returns the polar form of 22 | """ 23 | width = data.shape[1] 24 | height = data.shape[0] 25 | assert (width > 2) 26 | assert (height > 2) 27 | assert (width % 2 == 1) 28 | assert (height % 2 == 1) 29 | perimeter = 2 * (width + height - 2) 30 | halfdiag = math.ceil(((width ** 2 + height ** 2) ** 0.5) / 2) 31 | halfw = width // 2 32 | halfh = height // 2 33 | ret = np.zeros((halfdiag, perimeter)) 34 | 35 | # Don't want to deal with divide by zero errors... 36 | ret[0:(halfw + 1), halfh] = data[halfh, halfw::-1] 37 | ret[0:(halfw + 1), height + width - 2 + 38 | halfh] = data[halfh, halfw:(halfw * 2 + 1)] 39 | ret[0:(halfh + 1), height - 1 + halfw] = data[halfh:(halfh * 2 + 1), halfw] 40 | ret[0:(halfh + 1), perimeter - halfw] = data[halfh::-1, halfw] 41 | 42 | # Divide the image into 8 triangles, and use the same calculation on 43 | # 4 triangles at a time. This is possible due to symmetry. 44 | # This section is also responsible for the corner pixels 45 | for i in range(0, halfh): 46 | slope = (halfh - i) / (halfw) 47 | diagx = ((halfdiag ** 2)/(slope ** 2 + 1)) ** 0.5 48 | unit_xstep = diagx / (halfdiag - 1) 49 | unit_ystep = diagx * slope / (halfdiag - 1) 50 | for row in range(halfdiag): 51 | ystep = round(row * unit_ystep) 52 | xstep = round(row * unit_xstep) 53 | if ((halfh >= ystep) and halfw >= xstep): 54 | ret[row, i] = data[halfh - ystep, halfw - xstep] 55 | ret[row, height - 1 - i] = data[halfh + ystep, halfw - xstep] 56 | ret[row, height + width - 2 + 57 | i] = data[halfh + ystep, halfw + xstep] 58 | ret[row, height + width + height - 3 - 59 | i] = data[halfh - ystep, halfw + xstep] 60 | else: 61 | break 62 | 63 | # Remaining 4 triangles 64 | for j in range(1, halfw): 65 | slope = (halfh) / (halfw - j) 66 | diagx = ((halfdiag ** 2)/(slope ** 2 + 1)) ** 0.5 67 | unit_xstep = diagx / (halfdiag - 1) 68 | unit_ystep = diagx * slope / (halfdiag - 1) 69 | for row in range(halfdiag): 70 | ystep = round(row * unit_ystep) 71 | xstep = round(row * unit_xstep) 72 | if (halfw >= xstep and halfh >= ystep): 73 | ret[row, height - 1 + j] = data[halfh + ystep, halfw - xstep] 74 | ret[row, height + width - 2 - 75 | j] = data[halfh + ystep, halfw + xstep] 76 | ret[row, height + width + height - 3 + 77 | j] = data[halfh - ystep, halfw + xstep] 78 | ret[row, perimeter - j] = data[halfh - ystep, halfw - xstep] 79 | else: 80 | break 81 | return ret 82 | 83 | 84 | def polar_to_cartesian(data: np.ndarray, width: int, height: int) -> np.ndarray: 85 | """Returns the cartesian form of . 86 | 87 | is the original width of the cartesian image 88 | is the original height of the cartesian image 89 | """ 90 | assert (width > 2) 91 | assert (height > 2) 92 | assert (width % 2 == 1) 93 | assert (height % 2 == 1) 94 | perimeter = 2 * (width + height - 2) 95 | halfdiag = math.ceil(((width ** 2 + height ** 2) ** 0.5) / 2) 96 | halfw = width // 2 97 | halfh = height // 2 98 | ret = np.zeros((height, width)) 99 | 100 | # Don't want to deal with divide by zero errors... 101 | ret[halfh, halfw::-1] = data[0:(halfw + 1), halfh] 102 | ret[halfh, halfw:(halfw * 2 + 1)] = data[0:(halfw + 1), 103 | height + width - 2 + halfh] 104 | ret[halfh:(halfh * 2 + 1), halfw] = data[0:(halfh + 1), height - 1 + halfw] 105 | ret[halfh::-1, halfw] = data[0:(halfh + 1), perimeter - halfw] 106 | 107 | # Same code as above, except the order of the assignments are switched 108 | for i in range(0, halfh): 109 | slope = (halfh - i) / (halfw) 110 | diagx = ((halfdiag ** 2)/(slope ** 2 + 1)) ** 0.5 111 | unit_xstep = diagx / (halfdiag - 1) 112 | unit_ystep = diagx * slope / (halfdiag - 1) 113 | for row in range(halfdiag): 114 | ystep = round(row * unit_ystep) 115 | xstep = round(row * unit_xstep) 116 | if ((halfh >= ystep) and halfw >= xstep): 117 | ret[halfh - ystep, halfw - xstep] = \ 118 | data[row, i] 119 | ret[halfh + ystep, halfw - xstep] = \ 120 | data[row, height - 1 - i] 121 | ret[halfh + ystep, halfw + xstep] = \ 122 | data[row, height + width - 2 + i] 123 | ret[halfh - ystep, halfw + xstep] = \ 124 | data[row, height + width + height - 3 - i] 125 | else: 126 | break 127 | 128 | for j in range(1, halfw): 129 | slope = (halfh) / (halfw - j) 130 | diagx = ((halfdiag ** 2)/(slope ** 2 + 1)) ** 0.5 131 | unit_xstep = diagx / (halfdiag - 1) 132 | unit_ystep = diagx * slope / (halfdiag - 1) 133 | for row in range(halfdiag): 134 | ystep = round(row * unit_ystep) 135 | xstep = round(row * unit_xstep) 136 | if (halfw >= xstep and halfh >= ystep): 137 | ret[halfh + ystep, halfw - xstep] = \ 138 | data[row, height - 1 + j] 139 | ret[halfh + ystep, halfw + xstep] = \ 140 | data[row, height + width - 2 - j] 141 | ret[halfh - ystep, halfw + xstep] = \ 142 | data[row, height + width + height - 3 + j] 143 | ret[halfh - ystep, halfw - xstep] = \ 144 | data[row, perimeter - j] 145 | else: 146 | break 147 | 148 | # Repairs black/missing pixels in the transformed image 149 | for i in range(1, height - 1): 150 | for j in range(1, width - 1): 151 | if ret[i, j] == 0: 152 | ret[i, j] = (ret[i - 1, j] + ret[i + 1, j]) / 2 153 | return ret 154 | 155 | 156 | def get_gauss(n: int) -> List[float]: 157 | """Return the Gaussian 1D kernel for a diameter of 158 | Referenced from: https://stackoverflow.com/questions/11209115/ 159 | """ 160 | sigma = 0.3 * (n/2 - 1) + 0.8 161 | r = range(-int(n/2), int(n/2)+1) 162 | new_sum = sum([1 / (sigma * math.sqrt(2*math.pi)) * 163 | math.exp(-float(x)**2/(2*sigma**2)) for x in r]) 164 | # Ensure that the gaussian array adds up to one 165 | return [(1 / (sigma * math.sqrt(2*math.pi)) * 166 | math.exp(-float(x)**2/(2*sigma**2))) / new_sum for x in r] 167 | 168 | 169 | def vertical_gaussian(data: np.ndarray, n: int) -> np.ndarray: 170 | """Peforms a Gaussian blur in the vertical direction on . Returns 171 | the resulting numpy array. 172 | 173 | is the radius, where 1 pixel radius indicates no blur 174 | """ 175 | padding = n - 1 176 | width = data.shape[1] 177 | height = data.shape[0] 178 | padded_data = np.zeros((height + padding * 2, width)) 179 | padded_data[padding: -padding, :] = data 180 | ret = np.zeros((height, width)) 181 | kernel = None 182 | old_radius = - 1 183 | for i in range(height): 184 | radius = round(i * padding / (height - 1)) + 1 185 | # Recreate new kernel only if we have to 186 | if (radius != old_radius): 187 | old_radius = radius 188 | kernel = np.tile(get_gauss(1 + 2 * (radius - 1)), 189 | (width, 1)).transpose() 190 | ret[i, :] = np.sum(np.multiply( 191 | padded_data[padding + i - radius + 1:padding + i + radius, :], kernel), axis=0) 192 | return ret 193 | 194 | 195 | def add_chromatic(im, strength: float = 1, no_blur: bool = False): 196 | """Splits into red, green, and blue channels, then performs a 197 | 1D Vertical Gaussian blur through a polar representation. Finally, 198 | it expands the green and blue channels slightly. 199 | determines the amount of expansion and blurring. 200 | disables the radial blur 201 | """ 202 | r, g, b = im.split() 203 | rdata = np.asarray(r) 204 | gdata = np.asarray(g) 205 | bdata = np.asarray(b) 206 | if no_blur: 207 | # channels remain unchanged 208 | rfinal = r 209 | gfinal = g 210 | bfinal = b 211 | else: 212 | rpolar = cartesian_to_polar(rdata) 213 | gpolar = cartesian_to_polar(gdata) 214 | bpolar = cartesian_to_polar(bdata) 215 | 216 | bluramount = (im.size[0] + im.size[1] - 2) / 100 * strength 217 | if round(bluramount) > 0: 218 | rpolar = vertical_gaussian(rpolar, round(bluramount)) 219 | gpolar = vertical_gaussian(gpolar, round(bluramount*1.2)) 220 | bpolar = vertical_gaussian(bpolar, round(bluramount*1.4)) 221 | 222 | rcartes = polar_to_cartesian( 223 | rpolar, width=rdata.shape[1], height=rdata.shape[0]) 224 | gcartes = polar_to_cartesian( 225 | gpolar, width=gdata.shape[1], height=gdata.shape[0]) 226 | bcartes = polar_to_cartesian( 227 | bpolar, width=bdata.shape[1], height=bdata.shape[0]) 228 | 229 | rfinal = Image.fromarray(np.uint8(rcartes), 'L') 230 | gfinal = Image.fromarray(np.uint8(gcartes), 'L') 231 | bfinal = Image.fromarray(np.uint8(bcartes), 'L') 232 | 233 | # enlarge the green and blue channels slightly, blue being the most enlarged 234 | gfinal = gfinal.resize((round((1 + 0.018 * strength) * rdata.shape[1]), 235 | round((1 + 0.018 * strength) * rdata.shape[0])), Image.ANTIALIAS) 236 | bfinal = bfinal.resize((round((1 + 0.044 * strength) * rdata.shape[1]), 237 | round((1 + 0.044 * strength) * rdata.shape[0])), Image.ANTIALIAS) 238 | 239 | rwidth, rheight = rfinal.size 240 | gwidth, gheight = gfinal.size 241 | bwidth, bheight = bfinal.size 242 | rhdiff = (bheight - rheight) // 2 243 | rwdiff = (bwidth - rwidth) // 2 244 | ghdiff = (bheight - gheight) // 2 245 | gwdiff = (bwidth - gwidth) // 2 246 | 247 | # Centre the channels 248 | im = Image.merge("RGB", ( 249 | rfinal.crop((-rwdiff, -rhdiff, bwidth - rwdiff, bheight - rhdiff)), 250 | gfinal.crop((-gwdiff, -ghdiff, bwidth - gwdiff, bheight - ghdiff)), 251 | bfinal)) 252 | 253 | # Crop the image to the original image dimensions 254 | return im.crop((rwdiff, rhdiff, rwidth + rwdiff, rheight + rhdiff)) 255 | 256 | def add_jitter(im, pixels: int = 1): 257 | """Adds a small pixel offset to the Red and Blue channels of , 258 | resulting in a classic chromatic fringe effect. Very cheap computationally. 259 | how many pixels to offset the Red and Blue channels 260 | """ 261 | if pixels == 0: 262 | return im.copy() 263 | r, g, b = im.split() 264 | rwidth, rheight = r.size 265 | gwidth, gheight = g.size 266 | bwidth, bheight = b.size 267 | im = Image.merge("RGB", ( 268 | r.crop((pixels, 0, rwidth + pixels, rheight)), 269 | g.crop((0, 0, gwidth, gheight)), 270 | b.crop((-pixels, 0, bwidth - pixels, bheight)))) 271 | return im 272 | 273 | def blend_images(im, og_im, alpha: float = 1, strength: float = 1): 274 | """Blends original image as an overlay over , with 275 | an alpha value of . Resizes with respect to , 276 | before adding it as an overlay. 277 | """ 278 | og_im.putalpha(int(255 * alpha)) 279 | og_im = og_im.resize((round((1 + 0.018 * strength) * og_im.size[0]), 280 | round((1 + 0.018 * strength) * og_im.size[1])), Image.ANTIALIAS) 281 | 282 | hdiff = (og_im.size[1] - im.size[1]) // 2 283 | wdiff = (og_im.size[0] - im.size[0]) // 2 284 | og_im = og_im.crop((wdiff, hdiff, wdiff + im.size[0], hdiff + im.size[1])) 285 | im = im.convert('RGBA') 286 | 287 | final_im = Image.new("RGBA", im.size) 288 | final_im = Image.alpha_composite(final_im, im) 289 | final_im = Image.alpha_composite(final_im, og_im) 290 | final_im = final_im.convert('RGB') 291 | return final_im 292 | 293 | 294 | 295 | 296 | if __name__ == '__main__': 297 | ''' 298 | import argparse 299 | parser = argparse.ArgumentParser( 300 | description="Apply chromatic aberration and lens blur to images") 301 | parser.add_argument("filename", help="input filename") 302 | parser.add_argument("-s", "--strength", type=float, default=1.0, 303 | help="set blur/aberration strength, defaults to 1.0") 304 | parser.add_argument("-j", "--jitter", type=int, default=0, 305 | help="set color channel offset pixels, defaults to 0") 306 | parser.add_argument("-y", "--overlay", type=float, default=0.0, 307 | help="alpha of original image overlay, defaults to 0.0") 308 | parser.add_argument( 309 | "-n", "--noblur", help="disable radial blur", action="store_true") 310 | parser.add_argument( 311 | "-o", "--out", help="write to OUTPUT (supports multiple formats)") 312 | parser.add_argument( 313 | '-v', '--verbose', help="print status messages", action="store_true") 314 | args = parser.parse_args() 315 | 316 | ifile = args.filename 317 | im = Image.open(ifile) 318 | im1 = Image.open(ifile) 319 | ''' 320 | im = Image.open("sim1.jpg") 321 | 322 | # Ensure width and height are odd numbers 323 | if (im.size[0] % 2 == 0 or im.size[1] % 2 == 0): 324 | if (im.size[0] % 2 == 0): 325 | im = im.crop((0, 0, im.size[0] - 1, im.size[1])) 326 | im.load() 327 | if (im.size[1] % 2 == 0): 328 | im = im.crop((0, 0, im.size[0], im.size[1] - 1)) 329 | im.load() 330 | 331 | og_im = im.copy() 332 | img = Image.open("sim1.jpg") 333 | im = add_chromatic(im, strength=1, no_blur=True)# metodo da invocare per aggiungere effetto 334 | #modificare i valori per ottenere effetti più o meno calcati (vedere descrizione sotto il metodo) 335 | 336 | # im --> 337 | # img --> 338 | 339 | plt.figure(num='Fallimento NO CHROMATIC ABERRATION CORRECTION') 340 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 341 | plt.xticks([]), plt.yticks([]) 342 | plt.subplot(122),plt.imshow(im),plt.title('No Chromatic Aberration Correction') 343 | plt.xticks([]), plt.yticks([]) 344 | plt.show() 345 | 346 | #ok 347 | -------------------------------------------------------------------------------- /condensation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/condensation.png -------------------------------------------------------------------------------- /condensation/condensation-readme: -------------------------------------------------------------------------------- 1 | images to be superimposed for condensation 2 | -------------------------------------------------------------------------------- /condensation/condensation1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/condensation/condensation1.png -------------------------------------------------------------------------------- /condensation/condensation2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/condensation/condensation2.png -------------------------------------------------------------------------------- /condensation/condensation3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/condensation/condensation3.png -------------------------------------------------------------------------------- /deadpixel-fixedposition.py: -------------------------------------------------------------------------------- 1 | #set a black pixel at a specific position 2 | import numpy as np 3 | import cv2 4 | from matplotlib import pyplot as plt 5 | from PIL import Image 6 | 7 | 8 | img= cv2.imread('sim1.jpg') 9 | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 10 | 11 | 12 | img1 = cv2.imread('sim1.jpg') 13 | img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) 14 | h, w, _ = img1.shape 15 | #set pixel at coordinates 90, 150 to black color 16 | w=150 17 | h=90 18 | img1[h,w]=(0,0,0) 19 | img1 = Image.fromarray(img1) 20 | 21 | 22 | plt.figure(num='Fallimento DEADPIXEL') 23 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 24 | plt.xticks([]), plt.yticks([]) 25 | plt.subplot(122),plt.imshow(img1),plt.title('DeadPixel') 26 | plt.xticks([]), plt.yticks([]) 27 | plt.show() 28 | -------------------------------------------------------------------------------- /deadpixel200-fixedposition.py: -------------------------------------------------------------------------------- 1 | #set 200 dead pixel at fixed positions (organized in a grid) 2 | import numpy as np 3 | import cv2 4 | from matplotlib import pyplot as plt 5 | import random 6 | from PIL import Image 7 | 8 | img = Image.open('sim1.jpg') 9 | 10 | img1 = cv2.imread('sim1.jpg') 11 | img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) 12 | 13 | h, w, _ = img1.shape 14 | print('width: ', w) 15 | print('height:', h) 16 | 17 | count = 0 18 | w1 = w2 = int(w/20) # in base a questo 20 e al 10 sotto decido quanti pixel neri inserire 19 | h1 = h2 = int(h/10) 20 | w2 = w3 = w2 - 5 21 | h2 = h3 = h2 - 5 22 | countpixel = 0 23 | 24 | for y in range(0, 10): 25 | h2 = h2 + (h1*y) 26 | for x in range(0, 20): 27 | img1[h2,w2] = (255, 0, 0) #rossi per visibilità 28 | countpixel = countpixel + 1 29 | w2 = w2 + w1 30 | if x==19: 31 | h2 = h3 32 | w2 = w3 33 | 34 | img1 = Image.fromarray(img1) # esempio conversione 35 | 36 | print(countpixel) #valore di controllo per i pixel inseriti 37 | 38 | plt.figure(num='Fallimento DEADPIXEL Configurazione 3') 39 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 40 | plt.xticks([]), plt.yticks([]) 41 | plt.subplot(122),plt.imshow(img1),plt.title('DEADPIXEL - Configurazione 3') 42 | plt.xticks([]), plt.yticks([]) 43 | plt.show() 44 | 45 | #ok 46 | -------------------------------------------------------------------------------- /deadpixel50-fixedposition.py: -------------------------------------------------------------------------------- 1 | #set 50 dead pixel at fixed positions (organized in a grid) 2 | 3 | import numpy as np 4 | import cv2 5 | from matplotlib import pyplot as plt 6 | import random 7 | 8 | img = cv2.imread('sim1.jpg') 9 | 10 | img1 = cv2.imread('sim1.jpg') 11 | 12 | h, w, _ = img1.shape 13 | 14 | count = 0 15 | w1 = w2 = int((w-70)/10) # in base a questo 10 e al 5 sotto decido quanti pixel neri inserire 16 | h1 = h2 = int((h-70)/5) 17 | w2 = w3 = w2 - 5 18 | h2 = h3 = h2 - 5 19 | countpixel = 0 20 | 21 | # naturalmente bisogna sempre controllare con un paio di prove (o calcolandolo) 22 | # se si esce confini dell'immagine in elaborazione 23 | 24 | for y in range(0, 5): 25 | h2 = h2 + (h1*y) 26 | for x in range(0, 10): 27 | #print("h2 e w2: " + str(h2) +" e "+ str(w2)) 28 | #inserimento di randomicità per quanto riguarda 29 | #le coordinate in cui vengono posti i pixel neri (in fase sperimentale 30 | #considerato un valore fisso, in quanto deve essere replicabile e quindi 31 | #sempre uguale): 32 | # img1[(h2+random.randint(1,20)),(w2+random.randint(1,20))] = (0, 0, 0) 33 | #versione per fase sperimentale sotto ("tutto fisso") 34 | img1[h2,w2] = (255, 0, 0) #pixels rossi (per visibilità) in coordinate [h2,w2] 35 | countpixel = countpixel + 1 36 | w2 = w2 + w1 37 | if x==9: 38 | h2 = h3 39 | w2 = w3 40 | 41 | 42 | print(countpixel) #valore di controllo per l'inserimento del giusto numero 43 | #di pixel neri 44 | 45 | plt.figure(num='Fallimento DEADPIXEL Configurazione 2 - 50 pixel Neri') 46 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 47 | plt.xticks([]), plt.yticks([]) 48 | plt.subplot(122),plt.imshow(img1),plt.title('DEADPIXEL - Configurazione 2') 49 | plt.xticks([]), plt.yticks([]) 50 | plt.show() 51 | 52 | #ok 53 | -------------------------------------------------------------------------------- /dirtygrey3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/dirtygrey3.png -------------------------------------------------------------------------------- /dirtyonglass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/dirtyonglass.png -------------------------------------------------------------------------------- /failure_example/bandingfail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/bandingfail.jpg -------------------------------------------------------------------------------- /failure_example/black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/black.jpg -------------------------------------------------------------------------------- /failure_example/blurredimage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/blurredimage.jpg -------------------------------------------------------------------------------- /failure_example/brightness15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/brightness15.jpg -------------------------------------------------------------------------------- /failure_example/brightness25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/brightness25.jpg -------------------------------------------------------------------------------- /failure_example/broken1-fail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/broken1-fail.jpg -------------------------------------------------------------------------------- /failure_example/broken1-fail2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/broken1-fail2.jpg -------------------------------------------------------------------------------- /failure_example/chromabefail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/chromabefail.jpg -------------------------------------------------------------------------------- /failure_example/chromabefail2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/chromabefail2.jpg -------------------------------------------------------------------------------- /failure_example/condens.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/condens.jpg -------------------------------------------------------------------------------- /failure_example/dead1000pixel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/dead1000pixel.jpg -------------------------------------------------------------------------------- /failure_example/dead200pixel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/dead200pixel.jpg -------------------------------------------------------------------------------- /failure_example/dead50pixel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/dead50pixel.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel-10lines-5H5V.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel-10lines-5H5V.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel-1vertical-line.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel-1vertical-line.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel-3lines-2H1V.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel-3lines-2H1V.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel-5lines-3H2V.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel-5lines-3H2V.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel-carregg-obstacle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel-carregg-obstacle.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel-carreggiata.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel-carreggiata.jpg -------------------------------------------------------------------------------- /failure_example/deadpixel1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/deadpixel1.jpg -------------------------------------------------------------------------------- /failure_example/dirtyglass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/dirtyglass.jpg -------------------------------------------------------------------------------- /failure_example/dirtyglass2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/dirtyglass2.jpg -------------------------------------------------------------------------------- /failure_example/icebrigfail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/icebrigfail.jpg -------------------------------------------------------------------------------- /failure_example/icebrigfail2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/icebrigfail2.jpg -------------------------------------------------------------------------------- /failure_example/nobayerfilterimage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/nobayerfilterimage.jpg -------------------------------------------------------------------------------- /failure_example/nodemosfail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/nodemosfail.jpg -------------------------------------------------------------------------------- /failure_example/noiseredu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/noiseredu.jpg -------------------------------------------------------------------------------- /failure_example/noiseredu1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/noiseredu1.jpg -------------------------------------------------------------------------------- /failure_example/originale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/originale.jpg -------------------------------------------------------------------------------- /failure_example/rainglassfail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/rainglassfail.jpg -------------------------------------------------------------------------------- /failure_example/sharpnesscorr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/sharpnesscorr.jpg -------------------------------------------------------------------------------- /failure_example/white.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/failure_example/white.jpg -------------------------------------------------------------------------------- /ice/ice-readme: -------------------------------------------------------------------------------- 1 | ice failure - images to be superimposed 2 | -------------------------------------------------------------------------------- /ice/ice1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/ice/ice1.png -------------------------------------------------------------------------------- /ice/ice2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/ice/ice2.png -------------------------------------------------------------------------------- /ice/ice3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/ice/ice3.png -------------------------------------------------------------------------------- /ice/ice4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/ice/ice4.png -------------------------------------------------------------------------------- /nobayesfilter-greyscale.py: -------------------------------------------------------------------------------- 1 | #represent the no bayes filter (greyscale) failure 2 | import numpy as np 3 | import cv2 4 | from PIL import Image 5 | from matplotlib import pyplot as plt 6 | from matplotlib import image as mpimg 7 | import os 8 | 9 | def rgb2gray(rgb): 10 | return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140]) 11 | 12 | 13 | #2 approaches for transforming in greyscale 14 | #see also nobayesfilter-greyscale2.py 15 | #depending on your image detection algorithm, one or the other may be preferable 16 | img = mpimg.imread('sim1.jpg') 17 | gray = rgb2gray(img) 18 | 19 | plt.figure(num='Failure NO BAYER FILTER') 20 | plt.subplot(121),plt.imshow(img),plt.title('Original') 21 | plt.xticks([]), plt.yticks([]) 22 | plt.subplot(122),plt.imshow(gray),plt.title('Greyscale') 23 | plt.xticks([]), plt.yticks([]) 24 | plt.show() 25 | 26 | #ok 27 | -------------------------------------------------------------------------------- /nobayesfilter-greyscale2.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | from PIL import Image 4 | from matplotlib import pyplot as plt 5 | 6 | img = cv2.imread('sim1.jpg') 7 | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 8 | 9 | gray = Image.open('sim1.jpg').convert('LA') 10 | # in alcuni casi .convert('LA') potrebbe non funzionare e l'altra conversione 11 | # che ho utilizzato è .convert('L') 12 | 13 | plt.figure(num='Fallimento NO BAYER FILTER') 14 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 15 | plt.xticks([]), plt.yticks([]) 16 | plt.subplot(122),plt.imshow(gray),plt.title('Scala di Grigi') 17 | plt.xticks([]), plt.yticks([]) 18 | plt.show() 19 | 20 | #ok 21 | -------------------------------------------------------------------------------- /nodemos.py: -------------------------------------------------------------------------------- 1 | #adds the "no demosaicing failure" on input image sim1.jpg 2 | from PIL import Image 3 | from numpy import* 4 | import cv2 5 | from matplotlib import pyplot as plt 6 | 7 | # Open image and put it in a numpy array 8 | srcArray = cv2.imread('sim1.jpg') 9 | srcArray1 = Image.open("sim1.jpg") 10 | 11 | w, h, _ = srcArray.shape 12 | # Create target array, twice the size of the original image 13 | resArray = zeros((2*w, 2*h, 3), dtype=uint8) 14 | 15 | # Map the RGB values in the original picture according to the BGGR pattern# 16 | 17 | # Blue 18 | resArray[::2, ::2, 2] = srcArray[:, :, 2] 19 | 20 | # Green (top row of the Bayer matrix) 21 | resArray[1::2, ::2, 1] = srcArray[:, :, 1] 22 | 23 | # Green (bottom row of the Bayer matrix) 24 | resArray[::2, 1::2, 1] = srcArray[:, :, 1] 25 | 26 | # Red 27 | resArray[1::2, 1::2, 0] = srcArray[:, :, 0] 28 | 29 | resArray = cv2.cvtColor(resArray, cv2.COLOR_BGR2RGB) 30 | # Save the image 31 | imgOut = Image.fromarray(resArray, "RGB") 32 | #imgOut = imgOut.resize((h,w), Image.ANTIALIAS)#se usi questo comando non vedrò 33 | #i pixel distinti in R, G e B pixels 34 | # con predominanza di pixel G, ma 35 | #risulterà un'immagine verdastra 36 | #della stessa dim. dell'Originale 37 | #(non è proprio quello che si 38 | #vuole ottenere da questo effetto) 39 | # Save the image 40 | # imgOut.save("nodemos.png") 41 | 42 | plt.figure(num='Failure DEMOSAICING') 43 | plt.subplot(121),plt.imshow(srcArray1),plt.title('Original') 44 | plt.xticks([]), plt.yticks([]) 45 | plt.subplot(122),plt.imshow(imgOut),plt.title('No Demosaicing') 46 | plt.xticks([]), plt.yticks([]) 47 | plt.show() 48 | 49 | #ok 50 | -------------------------------------------------------------------------------- /noise.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | from matplotlib import pyplot as plt 4 | 5 | image = cv2.imread('sim.jpg') 6 | #img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # I think this can be removed 7 | 8 | img=np.array(im) 9 | #Speckle Noise 10 | #second value (the "1") is the Standard deviation (spread or "width") of the distribution 11 | gauss = np.random.normal(0,1,img.size) 12 | gauss = gauss.reshape(img.shape[0],img.shape[1],img.shape[2]).astype('uint8') 13 | noise = img + img * gauss 14 | 15 | plt.figure(num='Failure NOISE') 16 | plt.subplot(121),plt.imshow(img),plt.title('Original') 17 | plt.xticks([]), plt.yticks([]) 18 | plt.subplot(122),plt.imshow(noise),plt.title('Noise') 19 | plt.xticks([]), plt.yticks([]) 20 | plt.show() 21 | 22 | #ok 23 | -------------------------------------------------------------------------------- /overlay_images.py: -------------------------------------------------------------------------------- 1 | #It allow to overlay images without losing brightness, if the foreground image is transparent 2 | #The "overlay" is our approach to banding, rain, condensation, broken lens, ice, dirt failures. 3 | #The github contains some images that you can overlay to sim1.jpg, but others obviously exist. 4 | 5 | from matplotlib import pyplot as plt 6 | from PIL import Image 7 | import os 8 | import cv2 9 | 10 | 11 | 12 | img = Image.open("sim1.jpg") 13 | img3 = Image.open("sim1.jpg") 14 | #this works nice if the image to be overlayed (the foreground image, ice3.png in this case) is transparent 15 | img2 = Image.open("./ice/ice3.png").convert("RGBA") 16 | img3.paste(img2, (0, 0), img2) 17 | 18 | #Alternative approach, if foreground image is not transparent: 19 | #essenzially resize, blend, then add brightness to get as close as possible to the original image. 20 | 21 | #img2 = Image.open("broken1.png").convert(img.mode) # immagini da sovrapporre all'Originale 22 | #img2 = img2.resize(img.size) 23 | #img3 = Image.blend(img,img2,0.35)#valori per immagine banding->0.02, banding1->0.05, ice->0.2 24 | #then you can add some brightness 25 | #enhancer = ImageEnhance.Brightness(img3) 26 | #factor = 1.6 #choose a value 27 | #img3 = enhancer.enhance(factor) 28 | 29 | plt.figure(num='Overlay image') 30 | plt.subplot(121),plt.imshow(img),plt.title('Original') 31 | plt.xticks([]), plt.yticks([]) 32 | plt.subplot(122),plt.imshow(img3),plt.title('Overlaid image') 33 | #plt.subplot(122),plt.imshow(img3),plt.title('Overlaid image') 34 | plt.xticks([]), plt.yticks([]) 35 | plt.show() 36 | -------------------------------------------------------------------------------- /overlay_images2.py: -------------------------------------------------------------------------------- 1 | #see overlay_images.py for an alternative (better) method 2 | #Overlay is our approach to banding, rain, condensation, broken lens, ice, dirt. 3 | #The github contains some images that you can overlay to sim1.jpg, but many others obviously can be used. 4 | 5 | from matplotlib import pyplot as plt 6 | from PIL import Image 7 | 8 | 9 | img = Image.open("sim1.jpg") 10 | 11 | img2 = Image.open("broken1.png").convert(img.mode) # broken1.png is overlayed to sim1.jpg 12 | # pay attention that it may get the image darker 13 | # see overlay_images.py for alternatives 14 | 15 | img2 = img2.resize(img.size) 16 | 17 | img3 = Image.blend(img,img2,0.35)#valori per immagine banding->0.02, banding1->0.05, ice->0.2 18 | 19 | plt.figure(num='Fallimento BROKEN LENS') 20 | plt.subplot(121),plt.imshow(img),plt.title('Originale') 21 | plt.xticks([]), plt.yticks([]) 22 | plt.subplot(122),plt.imshow(img3),plt.title('Broken Lens') 23 | plt.xticks([]), plt.yticks([]) 24 | plt.show() 25 | 26 | #ok 27 | -------------------------------------------------------------------------------- /rain/rain-readme: -------------------------------------------------------------------------------- 1 | rain images to be superimposed 2 | -------------------------------------------------------------------------------- /rain/rain1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/rain/rain1.png -------------------------------------------------------------------------------- /rain/rain2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/rain/rain2.png -------------------------------------------------------------------------------- /rain/rain3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/rain/rain3.png -------------------------------------------------------------------------------- /rain/rain4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/rain/rain4.png -------------------------------------------------------------------------------- /rain/rain5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/rain/rain5.png -------------------------------------------------------------------------------- /rainglass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/rainglass.png -------------------------------------------------------------------------------- /sharpness.py: -------------------------------------------------------------------------------- 1 | from PIL import Image, ImageEnhance 2 | from matplotlib import pyplot as plt 3 | 4 | ''' 5 | Sharpness: This class can be used to adjust the sharpness 6 | of an image. An enhancement factor of 0.0 gives a 7 | blurred image, a factor of 1.0 gives the original 8 | image, and a factor of 2.0 gives a sharpened image. 9 | ''' 10 | 11 | img = Image.open("sim1.jpg") #se apri l'immagine con Image.open() non ci sono problemi 12 | # con i canali dei colori, se invece usi cv2.imread() 13 | # devi usare cv2.cvtColor(img, cv2.COLOR_BGR2RGB) per avere 14 | # colori corretti 15 | 16 | enhancer = ImageEnhance.Sharpness(img) 17 | 18 | factor = 1 19 | img1 = enhancer.enhance(factor) 20 | 21 | ''' 22 | 23 | esempi: 24 | 25 | factor = 1 --> img Originale 26 | factor = 3 --> img visibilmente più definita (non sempre un bene) 27 | factor = -3.5 --> img sfocata, non nitida (si avvicina molto al guasto Blurred) 28 | 29 | ''' 30 | 31 | factor = -3.5 32 | img2 = enhancer.enhance(factor) 33 | 34 | 35 | plt.figure(num='Fallimento SHARPNESS') 36 | plt.subplot(121),plt.imshow(img1),plt.title('Originale') 37 | plt.xticks([]), plt.yticks([]) 38 | plt.subplot(122),plt.imshow(img2),plt.title('Sharpened') 39 | plt.xticks([]), plt.yticks([]) 40 | plt.show() 41 | 42 | #ok 43 | -------------------------------------------------------------------------------- /sim1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/francescosecci/Python_Image_Failures/d4bc8ca61ff9bf3cce566c684cba7d8d7a50ea7b/sim1.jpg -------------------------------------------------------------------------------- /white.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from matplotlib import pyplot as plt 3 | 4 | picture1 = Image.open("sim.jpg") 5 | picture = Image.open("sim.jpg") 6 | 7 | pixels = picture.load() 8 | width, height = picture.size 9 | 10 | for i in range(0,width): 11 | for j in range(0,height): 12 | pixels[i,j] = (255, 255, 255) 13 | 14 | #picture e picture1 --> 15 | 16 | #il codice sotto serve come presentazione per mostrare il fallimento 17 | plt.figure(num='Fallimento WHITE') 18 | plt.subplot(121),plt.imshow(picture1),plt.title('Originale') 19 | plt.xticks([]), plt.yticks([]) 20 | plt.subplot(122),plt.imshow(picture),plt.title('White') 21 | plt.xticks([]), plt.yticks([]) 22 | plt.show() 23 | 24 | #ok 25 | --------------------------------------------------------------------------------