Image Manipulation¶
NumPy indexing enables powerful image transformations.
Channel Extraction¶
Separate RGB and alpha channels using indexing.
1. RGBA Channels¶
import numpy as np
import matplotlib.pyplot as plt
import PIL
import urllib
def main():
url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
print(f"{img.shape = }")
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
for i, title in enumerate(["R Channel", "G Channel", "B Channel", "Alpha"]):
axes[i].set_title(title, fontsize=15)
axes[i].imshow(img[:, :, i])
axes[i].axis('off')
plt.tight_layout()
plt.show()
if __name__ == "__main__":
main()
2. Single Channel¶
Access one channel with img[:, :, 0] for red, 1 for green, 2 for blue.
Basic Transforms¶
Apply geometric transformations using slicing.
1. Flip and Slice¶
import numpy as np
import matplotlib.pyplot as plt
import PIL
import urllib
def main():
url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
imgs = (img, img[::-1], img[:, ::-1],
img[:, :, ::-1], img[::7, ::7], img[50:-50, 50:-50])
titles = ("Original", "Flip Vertical", "Flip Horizontal",
"Swap Channels", "Downsample", "Crop")
fig, axes = plt.subplots(2, 3, figsize=(8, 5))
for ax, im, title in zip(axes.flat, imgs, titles):
ax.set_title(title, fontsize=12)
ax.imshow(im)
ax.axis('off')
plt.tight_layout()
plt.show()
if __name__ == "__main__":
main()
2. Operation Summary¶
img[::-1]— flip verticallyimg[:, ::-1]— flip horizontallyimg[:, :, ::-1]— reverse channel order (RGB→BGR)img[::7, ::7]— downsample by factor of 7img[50:-50, 50:-50]— crop 50 pixels from each edge
Grid Overlay¶
Draw grid lines on an image using slice assignment.
1. Manual Grid¶
import numpy as np
import matplotlib.pyplot as plt
import PIL
import urllib
def main():
url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(6, 4))
ax0.imshow(img)
spacing = 50
img_copy = img.copy()
img_copy[spacing::spacing, :] = [0, 0, 0, 255]
img_copy[:, spacing::spacing] = [0, 0, 0, 255]
ax1.imshow(img_copy)
for ax in (ax0, ax1):
ax.axis('off')
plt.tight_layout()
plt.show()
if __name__ == "__main__":
main()
2. Slice Assignment¶
img[::50, :] = color sets every 50th row to the specified color.
np.where Function¶
Conditional element replacement based on a condition.
1. Syntax Pattern¶
\[\begin{array}{cccccccc}
b&=&\text{np.where(}&\text{condition}&,&\text{if\_true}&,&\text{if\_false}&\text{)}
\end{array}\]
2. Add Noise Example¶
import numpy as np
import matplotlib.pyplot as plt
import PIL
import urllib
def main():
url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
img_noisy = img + np.random.randint(-100, 101, size=img.shape)
img_noisy = np.where(img_noisy >= 0, img_noisy, 0)
img_noisy = np.where(img_noisy <= 255, img_noisy, 255)
fig, ax = plt.subplots()
ax.imshow(img_noisy.astype(np.uint8))
ax.axis('off')
plt.show()
if __name__ == "__main__":
main()
3. Clipping Values¶
Chain np.where to clamp values within valid range [0, 255].
np.transpose¶
Swap array axes for transposition.
1. Image Transpose¶
import numpy as np
import matplotlib.pyplot as plt
import PIL
import urllib
def main():
url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
img_T = np.empty((img.shape[1], img.shape[0], 3), dtype=np.uint8)
img_T[:, :, 0] = img[:, :, 0].T
img_T[:, :, 1] = img[:, :, 1].T
img_T[:, :, 2] = img[:, :, 2].T
fig, ax = plt.subplots()
ax.imshow(img_T)
ax.axis('off')
plt.show()
if __name__ == "__main__":
main()
2. Channel-wise¶
Transpose each color channel separately to maintain RGB structure.
np.roll Function¶
Circular shift of array elements along an axis.
1. Roll Example¶
import numpy as np
import matplotlib.pyplot as plt
import PIL
import urllib
def main():
url = "https://upload.wikimedia.org/wikipedia/en/4/43/Pok%C3%A9mon_Mewtwo_art.png"
img = np.array(PIL.Image.open(urllib.request.urlopen(url)))
fig, (ax0, ax1, ax2) = plt.subplots(1, 3, figsize=(12, 3))
ax0.imshow(img)
ax1.imshow(np.roll(img, 50, axis=0))
ax2.imshow(np.roll(img, 50, axis=1))
for ax in (ax0, ax1, ax2):
ax.axis('off')
plt.tight_layout()
plt.show()
if __name__ == "__main__":
main()
2. Axis Parameter¶
axis=0 rolls vertically; axis=1 rolls horizontally.