Warning: Can not open [/home/conf/public_html/cgi-bin/show_python.log]. Ignore
cimg = img.copy()
if '_x' in ftype:
# filter[:, iy0] = cx
filter = np.zeros([ksize[0], 1])
filter[:, 0] = cx
cimg = cv2.filter2D(cimg, -1, filter)
if '_y' in ftype:
# filter[ix0, :] = cy
filter = np.zeros([1, ksize[1]])
filter[0, :] = cy
cimg = cv2.filter2D(cimg, -1, cy)
Download script from image_contrast.py
Related files:
image_contrast.gif
import sys
import numpy as np
from tqdm import tqdm, trange
from scipy.signal import savgol_coeffs
import cv2
import matplotlib.pyplot as plt
infile = 'stem.png'
outfile = 'normalized_image.png'
block_w = 20
block_h = 10
copy_w = 3
copy_h = 3
smooth_mode = 'poly' # 'gauss'
# for gauss and poly
smooth_w = 15
smooth_h = 15
# for poly
smooth_order = 3
view_w = 800
def usage():
print()
print(f"Usage: python {sys.argv[0]} infile block_w block_h copy_w copy_h view_w")
def initialize():
global infile, outfile, block_w, block_h, copy_w, copy_h
global smooth_mode, smooth_w, smooth_h, smooth_order
global view_w
infile = 'stem.png'
outfile = 'normalized_image.png'
block_w = 20
block_h = 10
copy_w = 3
copy_h = 3
smooth_mode = 'poly'
smooth_w = 15
smooth_h = 15
smooth_order = 3
view_w = 800
def update_vars():
global infile, outfile, block_w, block_h, copy_w, copy_h
global smooth_mode, smooth_w, smooth_h, smooth_order
global view_w
nargv = len(sys.argv)
if nargv >= 2: infile = sys.argv[1]
if nargv >= 3: block_w = int(sys.argv[2])
if nargv >= 4: block_h = int(sys.argv[3])
if nargv >= 5: copy_w = int(sys.argv[4])
if nargv >= 6: copy_h = int(sys.argv[5])
if nargv >= 7: smooth_mode = sys.argv[6]
if nargv >= 8: smooth_w = int(sys.argv[7])
if nargv >= 9: smooth_h = int(sys.argv[8])
if nargv >= 10: smooth_order = int(sys.argv[9])
if nargv >= 11: view_w = int(sys.argv[10])
def read_image(infile, color = cv2.IMREAD_GRAYSCALE):
print()
print(f"Read image [{infile}]")
return cv2.imread(infile, color)
def save_image(img, outfile):
print()
print(f"Save converted image to [{outfile}]")
cv2.imwrite(outfile, img)
def plot_image(img1, img2, img3, view_w = 600, mode = 'cv2'):
print()
print("plot")
if len(img1.shape) == 2:
height, width = img1.shape
else:
height, width, _ = img1.shape
print(f"image shape: {width} x {height}")
mag = view_w / width
print(f"view width: {view_w} = {width} * {mag:.3f}")
if img1 is not None:
img1_resized = cv2.resize(img1, (int(width * mag + 1.0e-5), int(height * mag + 1.0e-5)), interpolation=cv2.INTER_LINEAR)
if img2 is not None:
img2_resized = cv2.resize(img2, (int(width * mag + 1.0e-5), int(height * mag + 1.0e-5)), interpolation=cv2.INTER_LINEAR)
if img3 is not None:
img3_resized = cv2.resize(img3, (int(width * mag + 1.0e-5), int(height * mag + 1.0e-5)), interpolation=cv2.INTER_LINEAR)
if mode == 'cv2':
cv2.imshow('Original Image', img1_resized)
cv2.imshow('Converted Image', img2_resized)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
plt.figure(figsize=(15, 5))
if img1 is not None:
plt.subplot(1, 3, 1)
plt.title('Original Image')
plt.imshow(cv2.cvtColor(img1_resized, cv2.COLOR_BGR2RGB))
if img2 is not None:
plt.subplot(1, 3, 2)
plt.title('Smoothed Image')
plt.imshow(cv2.cvtColor(img2_resized, cv2.COLOR_BGR2RGB))
if img3 is not None:
plt.subplot(1, 3, 3)
plt.title('Converted Image')
plt.imshow(cv2.cvtColor(img3_resized, cv2.COLOR_BGR2RGB))
plt.pause(1.0e-5)
input("\nPress ENTER to terminate>>\n")
def smoothing(img, ftype, ksize, sigmaX = -1, norder = 3):
if 'gauss' in ftype:
print("gaussian smoothing:")
return cv2.GaussianBlur(img, ksize, sigmaX)
elif ftype == 'fft':
print("fft smoothing:")
fted = np.fft.fft2(img)
fted_shift = np.fft.fftshift(fted)
rows, cols = img.shape
cy, cx = rows // 2 , cols // 2
ry, rx = ksize
for iy in range(rows):
for ix in range(cols):
# r2 = ((ix - cx) / rx)**2 + ((iy - cy) / ry)**2
# if r2 > 1.0:
if iy < cy - ry or cy + ry < iy or ix < cx - rx or cx + rx < ix:
fted_shift[iy][ix] = 0.0
fted_origin = np.fft.ifftshift(fted_shift)
img_back = np.fft.ifft2(fted_origin)
img_back = np.abs(img_back)
# img_back = img_back / max(img_back.flatten()) * 255.0
img_back8 = np.zeros([rows, cols], np.uint8)
for iy in range(rows):
for ix in range(cols):
img_back8[iy][ix] = img_back[iy][ix].real
# return img_back.astype(np.uint8)
return img_back8
else:
print(f"{norder}-th order polynomial fit smoothing using {ksize[0]} x {ksize[1]} points:")
# filter = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) / 9.0
cx = savgol_coeffs(ksize[0], norder)
cy = savgol_coeffs(ksize[1], norder)
filter = np.zeros(ksize)
ix0 = int(ksize[0] / 2) + 1
iy0 = int(ksize[1] / 2) + 1
filter[:, iy0] = cx / cx[ix0]
filter[ix0, :] = cy / cy[iy0]
tot = sum(sum(row) for row in filter)
filter /= tot
cimg = cv2.filter2D(img, -1, filter)
'''
cimg = img.copy()
if '_x' in ftype:
# filter[:, iy0] = cx
filter = np.zeros([ksize[0], 1])
filter[:, 0] = cx
cimg = cv2.filter2D(cimg, -1, filter)
if '_y' in ftype:
# filter[ix0, :] = cy
filter = np.zeros([1, ksize[1]])
filter[0, :] = cy
cimg = cv2.filter2D(cimg, -1, cy)
'''
return cimg
def normalize_image(img, block_w, block_h, copy_w = 3, copy_h = 3):
hdx0 = int(block_w / 2)
hdy0 = int(block_h / 2)
hcx0 = int(copy_w / 2)
hcy0 = int(copy_h / 2)
img_normalized = img.copy()
height, width = img.shape
def get_range(i, imax, w0):
if i == 0 or i == imax - 1: w = 1
elif i < w0: w = i
elif imax - 1 - w0 < i: w = imax - w0
else: w = w0
range0 = i - w
range1 = i + w
if range0 < 0: range0 = 0
if imax <= range1: range1 = imax
return w, range0, range1
for yc in trange(0, height + 2 * hcy0, 2 * hcy0 + 1):
hdy, norm_y0, norm_y1 = get_range(yc, height, hdy0)
for xc in range(0, width + 2 * hcx0, 2 * hcx0 + 1):
hdx, norm_x0, norm_x1 = get_range(xc, width, hdx0)
# print(f"xc/{width}=", xc, hdx, norm_x0, norm_x1)
copy_y0 = yc - hcy0
copy_y1 = yc + hcy0
copy_x0 = xc - hcx0
copy_x1 = xc + hcx0
# print("copy:", copy_x0, copy_x1)
block = img[norm_y0:norm_y1 + 1, norm_x0:norm_x1 + 1]
vmin = block.min()
vmax = block.max()
# print("vmin,vmax=", vmin, vmax)
if vmin != vmax:
img_normalized[copy_y0:copy_y1 + 1, copy_x0:copy_x1 + 1] \
= (img[copy_y0:copy_y1 + 1, copy_x0:copy_x1 + 1] - vmin) / (vmax - vmin) * 255.0
return img_normalized
def main():
global infile, outfile, block_w, block_h, copy_w, copy_h, view_w, smooth_w, smooth_h
initialize()
update_vars()
img = read_image(infile)
height, width = img.shape
print("image shape:", height, width)
print("color range:", img.min(), img.max())
print("block size:")
print(" normalize:", block_w, block_h)
if copy_w > block_w: copy_w = block_w
if copy_h > block_h: copy_h = block_h
print(" copy :", copy_w, copy_h)
smooth_w = 2 * int(smooth_w / 2) + 1
smooth_h = 2 * int(smooth_h / 2) + 1
print(f"smoothing block ({smooth_mode}): {smooth_w} x {smooth_h}")
img_smoothed = smoothing(img, smooth_mode, (smooth_w, smooth_h), -1, smooth_order)
img_normalized = normalize_image(img_smoothed, block_w, block_h)
save_image(img_normalized, outfile)
plot_image(img, img_smoothed, img_normalized, view_w, mode = 'matplotlib')
# plot_image(img, ftr, fti, mode = 'matplotlib')
usage()
if __name__ == '__main__':
main()