Last active
March 26, 2019 09:51
-
-
Save nobodyzxc/2033966d7fdf4ac9170cd2bc865a5133 to your computer and use it in GitHub Desktop.
convolution implementation for CV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import cv2, sys, os.path | |
from itertools import chain | |
from functools import reduce | |
kernel = "smooth" | |
filename = "demo.png" | |
kernels = { | |
"blur" : [[5/80,1/8,5/80], | |
[ 1/8,1/4, 1/8], | |
[5/80,1/8,5/80]], | |
"topsobel" : [[ 1, 2, 1], | |
[ 0, 0, 0], | |
[ -1, -2, -1]], | |
"rightsobel": [[ -1, 0, 1], | |
[ -2, 0, 2], | |
[ -1, 0, 1]], | |
"emboss" : [[ -2, -1, 0], | |
[ -1, 1, 1], | |
[ 0, 1, 2]], | |
"smooth" : [[1/9, 1/9, 1/9], | |
[1/9, 1/9, 1/9], | |
[1/9, 1/9, 1/9]], | |
"sharpen" : [[ 0, -1, 0], | |
[ -1, 5, -1], | |
[ 0, -1, 0]], | |
"edgedet" : [[ -1, -1, -1], | |
[ -1, 8, -1], | |
[ -1, -1, -1]], | |
"identity": [[ 0, 0, 0], | |
[ 0, 1, 0], | |
[ 0, 0, 0]] | |
} | |
dot = lambda a, b: sum(i[0] * i[1] for i in zip(a, b)) | |
flatten = lambda it: list(chain.from_iterable(it)) | |
normalize = lambda v: min(max(v, 0), 255) | |
def conv(image, y, x, kernel): | |
K = flatten(kernel) | |
kh, kw = len(kernel), len(kernel[0]) | |
channels = zip(*[image[y + dy][x + dx] | |
for dy in range(-(kh // 2), kh // 2 + 1) | |
for dx in range(-(kw // 2), kw // 2 + 1)]) | |
return [dot(channel, K) for channel in channels] | |
if __name__ == '__main__': | |
if "-h" in sys.argv or "--help" in sys.argv: | |
print(sys.argv[0], "[file] [kernel name]\n") | |
print("kernels:", ' '.join(kernels.keys())), exit(0) | |
if len(sys.argv) > 1: filename = sys.argv[1] | |
if len(sys.argv) > 2: kernel = sys.argv[2] | |
if kernel not in kernels: print("kernel doesn't exist"), exit(1) | |
if not os.path.isfile(filename): print(filename, "doesn't exit"), exit(1) | |
img, kernel = cv2.imread(filename), kernels[kernel] | |
height, width = len(img), len(img[0]) | |
kh, kw = len(kernel), len(kernel[0]) | |
new = np.array([[[normalize(rgb) for rgb in conv(img, y, x, kernel)] | |
for x in range(kw // 2, width - kw // 2)] | |
for y in range(kh // 2, height - kh // 2)], | |
dtype=np.uint8) | |
cv2.namedWindow('origin', cv2.WINDOW_NORMAL) | |
cv2.namedWindow('conv', cv2.WINDOW_NORMAL) | |
cv2.imshow('origin', img), cv2.imshow('conv', new) | |
cv2.waitKey(0), cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment