Example usage

To use imgcv in a project:

Transformations

Negative Transformation

from imgcv.transformations.negative import negative_transform

im = Image.open("images/transformations/moon.tif")
im = np.array(im)
negative_im = negative_transform(im)

negative_im = Image.fromarray(negative_im)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(im, cmap="gray")
plt.title("Original Image")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.imshow(negative_im, cmap="gray")
plt.title("Negative Image")
plt.axis("off")
plt.show()
_images/b5b93ed53d2aa0bb406f2c3717248d3b261ac5a539eb36e1559468b2f98f15a6.png

Power-Law (Gamma) Transformation

from imgcv.transformations.gamma import gamma_correction

im = Image.open("images/transformations/city.tif")
im = np.array(im)
gamma_im = gamma_correction(im, gamma=3)

gamma_im = Image.fromarray(gamma_im)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(im, cmap="gray")
plt.title("Original Image")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.imshow(gamma_im, cmap="gray")
plt.title("Gamma Corrected Image")
plt.axis("off")
plt.show()
_images/c4cd941b5f1f8d1c23492c849fac3c13a67a2980925c34a577788d9b761a87d3.png

Histogram Equalization

For Gray Scale Images

from imgcv.histogram.histogram_equalization import histogram_equalization

im = Image.open("images/uni_dark.png")
im = im.convert("L")
im = np.array(im)

equalized_im, _ = histogram_equalization(im)
equalized_im = Image.fromarray(equalized_im)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(im, cmap="gray")
plt.title("Original Image")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.imshow(equalized_im, cmap="gray")
plt.title("Enhanced Image")
plt.axis("off")
plt.show()
_images/d4bd3223e81a08ef0104d808ce2f81ac26ef41623d3b506b51ae95e8ac93cbcf.png

For Color Image

from imgcv.histogram.histogram_equalization import histogram_equalization

im = Image.open("images/monkey_faded.webp")
im = np.array(im)

equalized_im, _ = histogram_equalization(im)
equalized_im = Image.fromarray(equalized_im)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(im)
plt.title("Original Image")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.imshow(equalized_im)
plt.title("Enhanced Image")
plt.axis("off")
plt.show()
_images/840e3cc154bdedd85d8bd92f6a89425ae464bc04b7445bb27bc2725517353410.png

Histogram Matching/Specification

from imgcv.histogram.matching import matchHistogram

img = Image.open("images/park.png").convert("RGB")
ref_img = Image.open("images/pretty_girl.webp")

final_img, _, _ = matchHistogram(np.array(img), np.array(ref_img))

plt.figure(figsize=(15, 5))
plt.subplot(131)
plt.imshow(img, cmap='gray')
plt.title('Input Image')
plt.axis("off")
plt.subplot(132)
plt.imshow(ref_img, cmap='gray')
plt.title('Reference Image')
plt.axis("off")
plt.subplot(133)
plt.imshow(final_img, cmap='gray')
plt.title('Output Image')
plt.axis("off")
plt.tight_layout()
plt.show()
_images/35e8a5d543820cb7e5bc41a9f8dbbc63848743816a820ca808ba1dd46bdc7166.png

Filters in Spatial Domain

Linear Filters

Mean / Average / Box Filter

from imgcv.filters.linear import box_filter

img = Image.open("images/alt.jpeg")
img = np.array(img)
smoothed_img = box_filter(img, filter_size=(7, 7))

fig, ax = plt.subplots(1, 2, figsize=(15, 10))
ax[0].imshow(img)
ax[0].set_title("Original Image")
ax[0].axis("off")
ax[1].imshow(smoothed_img)
ax[1].set_title("Box Filtered Image")
ax[1].axis("off")
plt.show()
_images/0edfa5deed39a2e6b7ceb596326e0e81a87cba87231577e649b16fe5a4212d35.png

Laplacian Filter

Detecting Edges
from imgcv.filters.linear import laplacian_filter

img = Image.open("images/pretty_girl.webp").convert("L")
img = np.array(img)
laplacian_img = laplacian_filter(img, diagonal=True, return_edges=True)

fig, ax = plt.subplots(1, 2, figsize=(20, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original image")
ax[0].axis("off")
ax[1].imshow(laplacian_img, cmap="gray")
ax[1].set_title("Laplacian Filtered image")
ax[1].axis("off")
plt.show()
_images/99b356d54d9f33d20adfb979948bdfca68df93b56e829c7fc8cde38e80bd36e0.png
Sharpening Image
from imgcv.filters.linear import laplacian_filter

img = Image.open("images/pretty_girl.webp")
img = np.array(img)
sharpened_img = laplacian_filter(img, diagonal=False, return_edges=False)

fig, ax = plt.subplots(1, 2, figsize=(20, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original image")
ax[0].axis("off")
ax[1].imshow(sharpened_img, cmap="gray")
ax[1].set_title("Sharpened image")
ax[1].axis("off")
plt.show()
_images/627291295b5228d984e31c44619a06671b27340b031b6ed4fc57bcc10e09acd5.png
Robert Cross Operator
from imgcv.filters.linear import robert_cross_filter

img = Image.open("images/girl_jumping.webp").convert("L")
img = np.array(img)

robert_cross_img = robert_cross_filter(img)
fig, ax = plt.subplots(1, 2, figsize=(20, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original image")
ax[0].axis("off")
ax[1].imshow(robert_cross_img, cmap="gray")
ax[1].set_title("Robert Cross image")
ax[1].axis("off")
plt.show()
_images/61cb8a6d5d8fc8e22653a7e5d5dfe5c2fc95b9cdd9f9972a605cab9d21fc48bc.png
Sobel Filter

Sobel Filter can be used to detect defects in the image which is an preprocessing step in many image processing applications or in automated inspection systems. For example, in the image below, the defects are detected using Sobel Filter.

from imgcv.filters.linear import sobel_filter

img = Image.open("images/contact_lens.tif").convert("L")
img = np.array(img)

sobel_img = sobel_filter(img)
fig, ax = plt.subplots(1, 2, figsize=(20, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original image")
ax[0].axis("off")
ax[1].imshow(sobel_img, cmap="gray")
ax[1].set_title("Sobel image")
ax[1].axis("off")
plt.show()
_images/c6fac18db65689b78fa5a83c9aacbf868fc0c658503e017994fb321e9a3d1d1e.png

We can see two edge defect near 4 and 5 o’clock position.

Non-Linear Filters

Min Filter

from imgcv.filters.non_linear import min_filter

img = Image.open("images/saturn_salt.png")
img = np.array(img)

reduced_noisy_img = min_filter(img, (5,5))

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Noisy img")
ax[0].axis("off")
ax[1].imshow(reduced_noisy_img, cmap="gray")
ax[1].set_title("Min Filtered Image")
ax[1].axis("off")
plt.show()
_images/b19547e03c339bce555101d576aaf0b37d06071177349af279af62b345e2aace.png

Max Filter

from imgcv.filters.non_linear import max_filter

img = Image.open("images/saturn_pepper.png")
img = np.array(img)

reduced_noisy_img = max_filter(img, (5,5))

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Noisy img")
ax[0].axis("off")
ax[1].imshow(reduced_noisy_img, cmap="gray")
ax[1].set_title("Max Filtered Image")
ax[1].axis("off")
plt.show()
_images/62e7ae14c456950d0c61959f02a330579d56bd9c1354c28220b62a3048f3f045.png

Median Filter

from imgcv.filters.non_linear import median_filter

img = Image.open("images/man_noisy.png")
img = np.array(img)

clean_image= median_filter(img, (5,5))

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Noisy img")
ax[0].axis("off")
ax[1].imshow(clean_image, cmap="gray")
ax[1].set_title("Clean Image")
ax[1].axis("off")
plt.show()
_images/7ffc8f2abe5bea3a385c20e57cfeb3bb2bf93e3ecd1e2ff2d46f5c74fede1f1e.png

Fourier Transform

Convert Image to Frequency Domain

from imgcv.fftpack.fft import fft2, fftshift

img = Image.open("images/ruler.tiff")
img = np.array(img)

img_fft = fft2(img)
img_fft = fftshift(img_fft)
img_fft = np.log(1 + np.abs(img_fft)) # taking log so that we can get a better visualization

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original img")
ax[0].axis("off")
ax[1].imshow(img_fft, cmap="hot")
ax[1].set_title("FFT of the image")
ax[1].axis("off")
plt.show()
_images/d9cc534336179d3ecd74f7d718cce2743d86d7ccfcb2b061f82b4b19ac85fbb2.png

Convert FFT Image to Spatial Domain

from imgcv.fftpack.fft import fft, ifft2

img = Image.open("images/ruler.tiff")
img = np.array(img)

img_fft = fft2(img)
img_fft = fftshift(img_fft) # shifting doen't affect the ifft result.

img_ifft = ifft2(img_fft)
img_ifft = np.abs(img_ifft) # taking absolute value to remove any complex part

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(np.log(1 + np.abs(img_fft)), cmap="gray")
ax[0].set_title("FFT of image")
ax[0].axis("off")
ax[1].imshow(img_ifft, cmap="gray")
ax[1].set_title("Original Image")
ax[1].axis("off")
plt.show()
_images/30c7836cc449a134768dbb497995987c230b742bf60d0827b7bdfeff8af38503.png

Filters in Frequency Domain

Low Pass Filter

from imgcv.filters.freq_domain import low_pass_filter

img = Image.open("images/bands.tif").convert("L")
img = img.resize((512, 512))
img = np.array(img)

low_pass_img = low_pass_filter(img,cutoff=30, order=2, type="butterworth", return_img_fft=False)

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original image")
ax[0].axis("off")
ax[1].imshow(low_pass_img, cmap="gray")
ax[1].set_title("Butterworth Low Pass Filtered Image")
ax[1].axis("off")
plt.show()
_images/725b542be0d4d0dbb89843aab43973d948d487f0a7506148a38d2459a60b6e84.png
from imgcv.filters.freq_domain import high_pass_filter

img = Image.open("images/bands.tif").convert("L")
img = img.resize((512, 512))
img = np.array(img)

high_pass_img = high_pass_filter(img, cutoff=50, type="gaussian", return_img_fft=False)

fig, ax = plt.subplots(1, 2, figsize=(10, 10))
ax[0].imshow(img, cmap="gray")
ax[0].set_title("Original Image")
ax[0].axis("off")
ax[1].imshow(high_pass_img, cmap="gray")
ax[1].set_title("Gaussian High Pass Filtered Image")
ax[1].axis("off")
plt.show()
_images/8ff1efaf018f12e372608e3a4772caaafe85fa8f5923e96179cc7a593550d0e5.png