Compare commits
32 Commits
a78dcd6f99
...
5baabae99d
Author | SHA1 | Date | |
---|---|---|---|
5baabae99d | |||
1ea1bde910 | |||
674f87d480 | |||
7af96d6bf6 | |||
7684e1408d | |||
9c469cf67a | |||
9d2903af60 | |||
6a93b04686 | |||
b52fff9deb | |||
3ffcd33efe | |||
9641641b61 | |||
3e8b607b97 | |||
f1cafc1eb1 | |||
25b3b30634 | |||
3ada720db9 | |||
56037b058b | |||
f5c235c3cd | |||
ab72da470e | |||
981e2a48ae | |||
1e8d9d844c | |||
7cfe566290 | |||
719bb487dd | |||
f88b6ec1a9 | |||
4907d0c0fb | |||
65708e4977 | |||
60a4f78fa6 | |||
c642fa430e | |||
674ce8dabe | |||
807f586841 | |||
5c1f346f2e | |||
e2602347d4 | |||
ec3ddd9c94 |
59
datasets/rafael/240424/plot_dates.py
Normal file
59
datasets/rafael/240424/plot_dates.py
Normal file
@ -0,0 +1,59 @@
|
||||
from datetime import datetime
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
import matplotlib.dates as mdates
|
||||
|
||||
from PIL import Image
|
||||
from PIL.ExifTags import TAGS
|
||||
|
||||
import os
|
||||
|
||||
os.chdir('photos')
|
||||
|
||||
names = []
|
||||
dates = []
|
||||
|
||||
for fileName in sorted(os.listdir()):
|
||||
image = Image.open(fileName)
|
||||
imageExif = image.getexif()
|
||||
dateTimeKey = list(TAGS.keys())[list(TAGS.values()).index('DateTime')]
|
||||
dateTime = imageExif[dateTimeKey]
|
||||
names += [fileName.replace('DSC0', '').replace('.JPG', '')]
|
||||
dates += [dateTime[:(-1 if fileName.endswith('.tif') else 0)]]
|
||||
|
||||
# Convert date strings to datetime
|
||||
dates = [datetime.strptime(d, "%Y:%m:%d %H:%M:%S") for d in dates]
|
||||
|
||||
# Choose some nice levels
|
||||
NUMBER_OF_LEVELS = 10
|
||||
actualLevels = range(-NUMBER_OF_LEVELS * 2 + 1, NUMBER_OF_LEVELS * 2 , 2)
|
||||
levels = np.tile(actualLevels,
|
||||
int(np.ceil(len(dates)/len(actualLevels))))[:len(dates)]
|
||||
|
||||
# Create figure and plot a stem plot with the date
|
||||
fig, ax = plt.subplots(figsize=(8.8, 4), layout="constrained")
|
||||
ax.set(title="Matplotlib release dates")
|
||||
|
||||
ax.vlines(dates, 0, levels, color="tab:red") # The vertical stems.
|
||||
ax.plot(dates, np.zeros_like(dates), "-o",
|
||||
color="k", markerfacecolor="w") # Baseline and markers on it.
|
||||
|
||||
# annotate lines
|
||||
for d, l, r in zip(dates, levels, names):
|
||||
ax.annotate(r, xy=(d, l),
|
||||
xytext=(-3, np.sign(l)*3), textcoords="offset points",
|
||||
horizontalalignment="right",
|
||||
verticalalignment="bottom" if l > 0 else "top")
|
||||
|
||||
# format x-axis with 4-month intervals
|
||||
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y:%m:%d %H:%M:%S"))
|
||||
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")
|
||||
|
||||
# remove y-axis and spines
|
||||
ax.yaxis.set_visible(False)
|
||||
ax.spines[["left", "top", "right"]].set_visible(False)
|
||||
|
||||
ax.margins(y=0.1)
|
||||
plt.show()
|
35
datasets/raise/analyze_bayer_filter_mean_denoiser.py
Normal file
35
datasets/raise/analyze_bayer_filter_mean_denoiser.py
Normal file
@ -0,0 +1,35 @@
|
||||
import numpy as np
|
||||
from utils import Color
|
||||
import os
|
||||
from tqdm import tqdm
|
||||
import rawpy
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
os.chdir('flat-field/NEF')
|
||||
|
||||
firstBayerFilterOccurrenceImages = []
|
||||
|
||||
for fileName in tqdm(os.listdir()):
|
||||
with rawpy.imread(fileName) as raw:
|
||||
colorDesc = raw.color_desc.decode('ascii')
|
||||
assert colorDesc == 'RGBG'
|
||||
assert np.array_equal(raw.raw_pattern, np.array([[0, 1], [3, 2]], dtype = np.uint8))
|
||||
# RG
|
||||
# GB
|
||||
firstBayerFilterOccurrenceImage = raw.raw_image_visible.copy()[:2, :2]
|
||||
firstBayerFilterOccurrenceImages += [firstBayerFilterOccurrenceImage]
|
||||
|
||||
firstBayerFilterOccurrenceImages = np.array(firstBayerFilterOccurrenceImages)
|
||||
print(rawImageVisible)
|
||||
|
||||
NUMBER_OF_COLORS = 3
|
||||
HEX_COLOR = '#' + '%02x' * NUMBER_OF_COLORS
|
||||
COLOR_BASE = 256
|
||||
|
||||
def getColor(colorIndex):
|
||||
return HEX_COLOR % tuple((255 if colorIndex == colorIndexTmp else 0) for colorIndexTmp in range(NUMBER_OF_COLORS))
|
||||
|
||||
for colorIndex, (colorY, colorX) in enumerate([(0, 0), (0, 1), (1, 1)]):
|
||||
X = firstBayerFilterOccurrenceImages[:, colorY, colorX] - np.mean(firstBayerFilterOccurrenceImages, axis = 0)[colorY, colorX]
|
||||
plt.hist(X, bins = len(set(X)), color = getColor(colorIndex), alpha = 0.3)
|
||||
plt.show()
|
@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import skimage.restoration
|
||||
from skimage import img_as_float
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
@ -8,23 +7,19 @@ import os
|
||||
from tqdm import tqdm
|
||||
import csv
|
||||
import rawpy
|
||||
from utils import Color
|
||||
from utils import Color, denoise, iterativeMean
|
||||
import matplotlib.pyplot as plt
|
||||
from scipy.ndimage import gaussian_filter
|
||||
|
||||
imagesFolderPath = 'rafael/arw'
|
||||
imagesFolderPathFileName = imagesFolderPath.replace('/', '_')
|
||||
# Among:
|
||||
# - `wavelet`
|
||||
# - `bilateral`
|
||||
# - `tv_chambolle`
|
||||
# - `mean`
|
||||
# `denoise` possible denoisers and `mean`.
|
||||
denoiser = 'mean'
|
||||
|
||||
raiseNotFlatFields = False
|
||||
# `[Color.RED, Color.GREEN_RIGHT, ...]` or `Color`.
|
||||
colors = Color
|
||||
|
||||
if denoiser != 'mean':
|
||||
denoise = getattr(skimage.restoration, f'denoise_{denoiser}')
|
||||
# `[Color.RED, Color.GREEN_RIGHT, ...]` or `Color` or `[None]` for not raw images.
|
||||
colors = [None]
|
||||
|
||||
imagesFileNames = os.listdir(imagesFolderPath + ('/png' if raiseNotFlatFields else ''))
|
||||
|
||||
@ -79,83 +74,78 @@ def getImageNpArray(imageFileName, computeExtremes, color):
|
||||
|
||||
match color:
|
||||
case Color.RED:
|
||||
colorRawImageVisible = redRawImageVisible
|
||||
imageNpArray = redRawImageVisible
|
||||
case Color.GREEN_RIGHT:
|
||||
colorRawImageVisible = greenRightRawImageVisible
|
||||
imageNpArray = greenRightRawImageVisible
|
||||
case Color.GREEN_BOTTOM:
|
||||
colorRawImageVisible = greenBottomRawImageVisible
|
||||
imageNpArray = greenBottomRawImageVisible
|
||||
case Color.BLUE:
|
||||
colorRawImageVisible = blueRawImageVisible
|
||||
|
||||
if computeExtremes:
|
||||
colorRawImageVisibleMin = colorRawImageVisible.min()
|
||||
colorRawImageVisibleMax = colorRawImageVisible.max()
|
||||
if minColor is None or colorRawImageVisibleMin < minColor:
|
||||
minColor = colorRawImageVisibleMin
|
||||
if maxColor is None or colorRawImageVisibleMax > maxColor:
|
||||
maxColor = colorRawImageVisibleMax
|
||||
return
|
||||
imageNpArray = (colorRawImageVisible - minColor) / (maxColor - minColor)
|
||||
# Pay attention to range of values expected by the denoiser.
|
||||
# Indeed if provide the thousands valued raw image, then the denoiser only returns values between 0 and 1 and making the difference between both look pointless.
|
||||
imageNpArray = blueRawImageVisible
|
||||
else:
|
||||
imagePil = Image.open(imageFilePath)
|
||||
imageNpArray = img_as_float(np.array(imagePil))
|
||||
|
||||
if computeExtremes:
|
||||
colorRawImageVisibleMin = imageNpArray.min()
|
||||
colorRawImageVisibleMax = imageNpArray.max()
|
||||
if minColor is None or colorRawImageVisibleMin < minColor:
|
||||
minColor = colorRawImageVisibleMin
|
||||
if maxColor is None or colorRawImageVisibleMax > maxColor:
|
||||
maxColor = colorRawImageVisibleMax
|
||||
return
|
||||
|
||||
if (imageFileName.endswith('.NEF') or imageFileName.endswith('.ARW')) and denoiser != 'mean':
|
||||
imageNpArray = (imageNpArray - minColor) / (maxColor - minColor)
|
||||
# Pay attention to range of values expected by the denoiser.
|
||||
# Indeed if provide the thousands valued raw image, then the denoiser only returns values between 0 and 1 and making the difference between both look pointless.
|
||||
return imageNpArray
|
||||
|
||||
# `color` is the actual color to estimate PRNU with.
|
||||
def treatImage(imageFileName, computeExtremes = False, color = None):
|
||||
global mean, numberOfImagesInMean
|
||||
global estimatedPrnuIterativeMean
|
||||
imageNpArray = getImageNpArray(imageFileName, computeExtremes, color)
|
||||
if imageNpArray is None:
|
||||
return
|
||||
match denoiser:
|
||||
case 'wavelet':
|
||||
imageDenoisedNpArray = denoise(imageNpArray, rescale_sigma=True)
|
||||
case 'bilateral':
|
||||
imageDenoisedNpArray = denoise(imageNpArray, sigma_color=0.05, sigma_spatial=15)
|
||||
case 'tv_chambolle':
|
||||
imageDenoisedNpArray = denoise(imageNpArray, weight=0.2)
|
||||
case 'mean':
|
||||
imageDenoisedNpArray = imageNpArray - means[color]
|
||||
imageNoiseNpArray = imageNpArray - imageDenoisedNpArray
|
||||
if mean is None:
|
||||
mean = imageNoiseNpArray
|
||||
if denoiser != 'mean':
|
||||
imageDenoisedNpArray = denoise(imageNpArray, denoiser)
|
||||
else:
|
||||
mean = ((mean * numberOfImagesInMean) + imageNoiseNpArray) / (numberOfImagesInMean + 1)
|
||||
numberOfImagesInMean += 1
|
||||
imageDenoisedNpArray = means[color]
|
||||
imageNoiseNpArray = imageNpArray - imageDenoisedNpArray
|
||||
estimatedPrnuIterativeMean.add(imageNoiseNpArray)
|
||||
|
||||
# Assuming same intensity scale across color channels.
|
||||
for imageFileName in tqdm(imagesFileNames, 'Computing extremes of images'):
|
||||
for color in colors:
|
||||
treatImage(imageFileName, computeExtremes = True, color = color)
|
||||
if (minColor is None or maxColor is None) and denoiser != 'mean':
|
||||
# Assuming same intensity scale across color channels.
|
||||
for imageFileName in tqdm(imagesFileNames, 'Computing extremes of images'):
|
||||
for color in colors:
|
||||
treatImage(imageFileName, computeExtremes = True, color = color)
|
||||
|
||||
# To skip this step next time.
|
||||
# Maybe thanks to `rawpy.RawPy` fields, possibly stating device maximal value, can avoid doing so to some extent.
|
||||
print(f'{minColor=}')
|
||||
print(f'{maxColor=}')
|
||||
# To skip this step next time.
|
||||
# Maybe thanks to `rawpy.RawPy` fields, possibly stating device maximal value, can avoid doing so to some extent.
|
||||
print(f'{minColor=}')
|
||||
print(f'{maxColor=}')
|
||||
|
||||
def saveNpArray(fileName, npArray):
|
||||
with open(f'{fileName}.npy', 'wb') as f:
|
||||
np.save(f, npArray)
|
||||
|
||||
if denoiser == 'mean':
|
||||
means = {}
|
||||
for color in Color:
|
||||
colorMean = None
|
||||
numberOfImagesInColorMean = 0
|
||||
for imageFileName in tqdm(imagesFileNames, f'Computing mean of {color} images'):
|
||||
for color in colors:
|
||||
colorIterativeMean = iterativeMean()
|
||||
for imageFileName in tqdm(imagesFileNames, f'Computing mean of {color} colored images'):
|
||||
imageNpArray = getImageNpArray(imageFileName, False, color)
|
||||
if colorMean is None:
|
||||
colorMean = imageNpArray
|
||||
else:
|
||||
colorMean = ((colorMean * numberOfImagesInColorMean) + imageNpArray) / (numberOfImagesInColorMean + 1)
|
||||
numberOfImagesInColorMean += 1
|
||||
means[color] = colorMean
|
||||
imageNpArray = gaussian_filter(imageNpArray, sigma = 5)
|
||||
colorIterativeMean.add(imageNpArray)
|
||||
means[color] = colorIterativeMean.mean
|
||||
fileName = f'mean_{imagesFolderPathFileName}_{color}'
|
||||
# Then use `merge_single_color_channel_images_according_to_bayer_filter.py` to consider all color channels, instead of saving this single color channel as an image.
|
||||
saveNpArray(fileName, colorIterativeMean.mean)
|
||||
|
||||
for color in colors:
|
||||
mean = None
|
||||
numberOfImagesInMean = 0
|
||||
estimatedPrnuIterativeMean = iterativeMean()
|
||||
|
||||
for imageFileName in tqdm(imagesFileNames, f'Denoising images for color {color}'):
|
||||
treatImage(imageFileName, color = color)
|
||||
|
||||
npArrayFilePath = f'mean_{imagesFolderPathFileName}_{denoiser}_{color}.npy'
|
||||
with open(npArrayFilePath, 'wb') as f:
|
||||
np.save(f, mean)
|
||||
npArrayFilePath = f'mean_{imagesFolderPathFileName}_{denoiser}_{color}'
|
||||
saveNpArray(npArrayFilePath, estimatedPrnuIterativeMean.mean)
|
||||
|
92
datasets/raise/flat-field_pointer.py
Normal file
92
datasets/raise/flat-field_pointer.py
Normal file
@ -0,0 +1,92 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.backend_bases import MouseButton
|
||||
import matplotlib.image as mpimg
|
||||
import os
|
||||
from tqdm import tqdm
|
||||
|
||||
# `Zoom to rectangle` shortcut is `o`.
|
||||
|
||||
os.chdir('flat-field/TIF')
|
||||
|
||||
fileNames = sorted(os.listdir())[41:]
|
||||
fileNameIndex = 0
|
||||
xys = []
|
||||
progressBar = tqdm(total = len(fileNames))
|
||||
|
||||
def displayImage():
|
||||
global fileNameIndex
|
||||
if len(fileNames) > fileNameIndex:
|
||||
fileName = fileNames[fileNameIndex]
|
||||
image = mpimg.imread(fileName)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
ax.imshow(image)
|
||||
fileNameIndex += 1
|
||||
plt.connect('button_press_event', onClick)
|
||||
|
||||
mng = plt.get_current_fig_manager()
|
||||
mng.full_screen_toggle()
|
||||
|
||||
fig.canvas.toolbar.zoom()
|
||||
fig.show()
|
||||
|
||||
def onClick(event):
|
||||
global xys
|
||||
button = event.button
|
||||
if button is MouseButton.RIGHT:
|
||||
xy = [event.xdata, event.ydata]
|
||||
xys += [xy]
|
||||
if button is MouseButton.MIDDLE or button is MouseButton.RIGHT:
|
||||
if button is MouseButton.MIDDLE:
|
||||
print(f'Skipped {fileName}')
|
||||
plt.close()
|
||||
displayImage()
|
||||
progressBar.update(1)
|
||||
|
||||
displayImage()
|
||||
|
||||
##
|
||||
|
||||
xys = [[3061.83568617998, 842.2814890347822], [3048.9553647053262, 891.7951806771933], [3109.6923734795832, 878.8472318972372], [3095.1992301129835, 859.646383417094], [3044.950680354029, 830.531447782855], [3034.039239345914, 775.7097977790371], [3034.0562409262707, 753.1780473232427], [2991.7499740162116, 742.1417475753151], [3021.5541233968024, 737.7119154247914], [3022.412107608028, 703.0028101114289], [3094.4565209481857, 680.7339885543926], [3101.840188177543, 692.6886985125186], [3150.09819940581, 686.3913997808281], [3148.4955568040136, 694.3747788064451], [3165.156239230552, 703.9346483213995], [3158.7235775979357, 710.9522942666542], [3156.5302112965014, 697.5993396871294], [3106.8119050930513, 698.4561327048264], [3151.4728367372877, 694.3380683877142], [3137.283014559081, 662.9543422436452], [3008.1987322850605, 692.0180565561739], [3036.647953172549, 705.1188029786949], [2988.9166660643627, 684.0851408200217], [3001.5070402052334, 684.1944057536488], [2967.282534077184, 680.6072888791263], [2983.5140619626286, 693.469904886339], [2979.972210442175, 702.9033995969894], [2974.7535915953795, 709.6086279669086], [2972.55952140686, 700.4689248964266], [2967.1769510144627, 703.4861098128929], [2968.4714535085923, 708.5924315970815], [2978.725084963369, 725.0064286729727], [2992.7472737250696, 718.9682686788141], [2999.106406229902, 713.0463041988097], [2981.5746364633296, 692.5739107725338], [3014.22885383495, 675.1638989177214], [3004.351989366563, 635.6738446427469], [2964.9109157636794, 580.2416938434527], [2976.672441933737, 599.3922555819147], [2972.9623072548534, 578.6218471929612], [2694.5865522760287, 972.5526873692775], [2924.1211630176217, 1115.9816839025543], [2910.2861978522596, 1095.5172128924614], [2917.4530137143342, 1067.9680470058072], [2919.3469031337613, 1068.44539073963], [2959.4757277956496, 1105.6227950624348], [2936.370033263817, 1157.9142039933472], [2965.3568614486203, 1145.3186319170795], [2951.1991473505136, 1070.8989245366433], [2946.108094501549, 1045.891549058405], [2947.19213475732, 1074.4303801863052], [2943.690837961984, 1071.4536958497956], [3021.083385372544, 1116.881810271317], [3051.7205580454297, 1103.0992679894152], [3107.0873956690143, 972.8919609441568], [2861.932349690137, 1131.4847600231471], [2789.583044951935, 964.6512841164608]]
|
||||
|
||||
x, y = [[xy[dimensionIndex] for xy in xys] for dimensionIndex in range(2)]
|
||||
|
||||
plt.title('Center wall marker locations')
|
||||
|
||||
plt.scatter(x, y, c = range(len(x)))
|
||||
for xyIndex, xy in enumerate(xys):
|
||||
plt.text(xy[0], xy[1] + 10, str(xyIndex), horizontalalignment = 'center')
|
||||
|
||||
plt.show()
|
||||
|
||||
##
|
||||
|
||||
greatestDistances = []
|
||||
|
||||
#for xy in xys:
|
||||
for xy, otherXy in zip(xys, xys[1:]):
|
||||
greatestDistance = None
|
||||
#for otherXy in xys:
|
||||
if xy != otherXy:
|
||||
distance = sum([(xy[dimensionIndex] - otherXy[dimensionIndex]) ** 2 for dimensionIndex in range(2)]) ** 0.5
|
||||
if greatestDistance is None or distance > greatestDistance:
|
||||
greatestDistance = distance
|
||||
greatestDistances += [greatestDistance]
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
plt.title('Distance between a wall marker location and the next one')
|
||||
ax.boxplot(greatestDistances)
|
||||
|
||||
ys = []
|
||||
|
||||
for percentile in [25, 50, 75]:
|
||||
y = np.percentile(greatestDistances, percentile)
|
||||
ys += [y]
|
||||
ax.axhline(y = y)
|
||||
|
||||
ax.set_yticks(list(ax.get_yticks())[1:-1] + ys)
|
||||
|
||||
ax.set_xticks([], [])
|
||||
fig.show()
|
41
datasets/raise/generate_histogram.py
Normal file
41
datasets/raise/generate_histogram.py
Normal file
@ -0,0 +1,41 @@
|
||||
import os
|
||||
from PIL import Image
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from tqdm import tqdm
|
||||
|
||||
os.chdir('flat-field/TIF')
|
||||
|
||||
NUMBER_OF_COLORS = 3
|
||||
HEX_COLOR = '#' + '%02x' * NUMBER_OF_COLORS
|
||||
COLOR_BASE = 256
|
||||
|
||||
def getColor(colorIntensity, colorIndex):
|
||||
return HEX_COLOR % tuple((colorIntensity if colorIndex == colorIndexTmp else 0) for colorIndexTmp in range(NUMBER_OF_COLORS))
|
||||
|
||||
def getHistogram(fileName):
|
||||
image = Image.open(fileName)
|
||||
#image = image.crop((1, 1, 2, 2))
|
||||
#print(image.size)
|
||||
|
||||
histogram = image.histogram()
|
||||
|
||||
colors = [histogram[COLOR_BASE * colorIndex:COLOR_BASE * (colorIndex + 1)] for colorIndex in range(NUMBER_OF_COLORS)]
|
||||
return colors
|
||||
|
||||
def plotHistogram(colors):
|
||||
for colorIndex, color in enumerate(colors):
|
||||
for colorIntensity in range(COLOR_BASE):
|
||||
plt.bar(colorIntensity, color[colorIntensity], color = getColor(colorIntensity, colorIndex), alpha = 0.3)
|
||||
|
||||
fileNameColors = []
|
||||
|
||||
for fileName in tqdm(os.listdir()):
|
||||
colors = getHistogram(fileName)
|
||||
fileNameColors += [colors]
|
||||
|
||||
meanFileNameColors = np.mean(fileNameColors, axis = 0)
|
||||
|
||||
plotHistogram(meanFileNameColors)
|
||||
|
||||
plt.show()
|
@ -41,4 +41,4 @@ for color in tqdm(Color, 'Color'):
|
||||
|
||||
multipleColorsImage[newX, newY] = pixel
|
||||
|
||||
plt.imsave(PREFIX + 'multiple_colors.png', multipleColorsImage)
|
||||
plt.imsave(PREFIX + 'multiple_colors.png', multipleColorsImage)
|
@ -3,7 +3,8 @@ import matplotlib.pyplot as plt
|
||||
|
||||
fileName = 'mean_flat-field_nef_wavelet_blue'
|
||||
npArray = np.load(f'{fileName}.npy')
|
||||
print(f'{npArrayMin=}')
|
||||
# For other than raw images:
|
||||
#npArray = (npArray - npArray.min()) / (npArray.max() - npArray.min())
|
||||
plt.imsave(f'{fileName}.png', npArray)
|
||||
#plt.imshow(npArray)
|
||||
#plt.show()
|
@ -2,19 +2,16 @@ from PIL import Image
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from tqdm import tqdm
|
||||
from skimage.restoration import denoise_tv_chambolle
|
||||
from utils import denoise
|
||||
from skimage import img_as_float
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, '../../algorithms/image_utils/')
|
||||
|
||||
from image_utils import showImageWithMatplotlib, toPilImage
|
||||
|
||||
sys.path.insert(0, '../../algorithms/distance/')
|
||||
|
||||
from rms_diff import rmsDiffNumpy
|
||||
|
||||
NUMBER_OF_SUBGROUPS = 1
|
||||
DENOISER = 'wavelet'
|
||||
|
||||
IMAGES_FOLDER = 'flat-field/TIF'
|
||||
imagesFileNames = os.listdir(IMAGES_FOLDER)
|
||||
@ -31,7 +28,7 @@ for subgroupIndex in range(NUMBER_OF_SUBGROUPS):
|
||||
imagePath = f'{IMAGES_FOLDER}/{imageFileName}'
|
||||
imagePil = Image.open(imagePath)
|
||||
imageNpArray = img_as_float(np.array(imagePil))
|
||||
imagePrnuEstimateNpArray = imageNpArray - denoise_tv_chambolle(imageNpArray, weight=0.2, channel_axis=-1)
|
||||
imagePrnuEstimateNpArray = imageNpArray - denoise(imageNpArray, DENOISER)
|
||||
imagesPrnuEstimateNpArray += [imagePrnuEstimateNpArray]
|
||||
|
||||
subgroupPrnuEstimateNpArray = []
|
||||
@ -46,7 +43,7 @@ for numberOfImagesIndex, numberOfImages in enumerate(numberOfImagesThresholds):
|
||||
rms = rmsDiffNumpy(subgroupsPrnuEstimatesNpArray[0][numberOfImagesIndex], subgroupsPrnuEstimatesNpArray[1][numberOfImagesIndex])
|
||||
rmss += [rms]
|
||||
|
||||
plt.title('RMS between both subgroups estimated PRNUs for a given number of images among them')
|
||||
plt.title(f'RMS between both subgroups estimated PRNUs with {DENOISER} denoiser for a given number of images among them')
|
||||
plt.xlabel('Number of images of each subgroup')
|
||||
plt.ylabel('RMS between both subgroups estimated PRNUs')
|
||||
plt.plot(rmss)
|
||||
|
@ -1,4 +1,5 @@
|
||||
from enum import Enum, auto
|
||||
import skimage.restoration
|
||||
|
||||
class Color(Enum):
|
||||
RED = auto()
|
||||
@ -8,3 +9,27 @@ class Color(Enum):
|
||||
|
||||
def __str__(self):
|
||||
return self.name.lower()
|
||||
|
||||
# Among:
|
||||
# - `wavelet`
|
||||
# - `bilateral`
|
||||
# - `tv_chambolle`
|
||||
def denoise(imageNpArray, denoiserName):
|
||||
skImageRestorationDenoise = getattr(skimage.restoration, f'denoise_{denoiserName}')
|
||||
|
||||
match denoiserName:
|
||||
case 'wavelet':
|
||||
imageDenoisedNpArray = skImageRestorationDenoise(imageNpArray, rescale_sigma=True)
|
||||
case 'bilateral':
|
||||
imageDenoisedNpArray = skImageRestorationDenoise(imageNpArray, sigma_color=0.05, sigma_spatial=15)
|
||||
case 'tv_chambolle':
|
||||
imageDenoisedNpArray = skImageRestorationDenoise(imageNpArray, weight=0.2)
|
||||
return imageDenoisedNpArray
|
||||
|
||||
class iterativeMean:
|
||||
mean = None
|
||||
numberOfElementsInMean = 0
|
||||
|
||||
def add(self, element):
|
||||
self.mean = ((self.mean * self.numberOfElementsInMean) + element) / (self.numberOfElementsInMean + 1)
|
||||
self.numberOfElementsInMean += 1
|
Loading…
Reference in New Issue
Block a user