先直接来一个3×3的吧
def median(src_img, filter_size, channels): # 首先,定义一个大小为9的0数组 # list = [[0, 0, 0, 0, 0, 0, 0, 0, 0], # [0, 0, 0, 0, 0, 0, 0, 0, 0], # [0, 0, 0, 0, 0, 0, 0, 0, 0]] list = np.zeros([3, 9]) # print(list[1][4]) rows = src_img.shape[0] cols = src_img.shape[1] # list = [[1, 2, 3], [3, 1, 2]] # list[1].sort() # print(list[1]) # 新建一张相同大小的空白黑色图像 empty = np.zeros([rows, cols, channels], np.uint8) # 然后开始遍历 # 首先遍历所有图像像素(边框除外) for i in range(1, rows - 1): for j in range(1, cols - 1): # 分通道取中值 for c in range(0, channels): # 用于计数:计当前计到了九宫格的第几个像素 count = 0 for k in range(i - 1, i + 2): for m in range(j - 1, j + 2): list[c][count] = src_img[k, m, c] count += 1 # 所有的赋值都结束后,再分通道取中值,并将其赋给空白图像中的对应位置 for r in range(0, channels): # print(list[r]) list[r].sort() empty[i, j, r] = list[r][4] # print(empty) return empty
下面是具有一定普适性的改进版:
def median(src_img, filter_size): # 首先获取图像通道数 # 注意,关于ndim的最为直接的理解方式是:要表示一个元素最少需要几个下标,ndim就是几 if src_img.ndim == 2: channels = 1 elif src_img.ndim == 3: channels = 3 else: raise ValueError("the parameter must be a picture! It cannot be a picture!") pixel_list = np.zeros([channels, filter_size * filter_size]) rows = src_img.shape[0] cols = src_img.shape[1] # 新建一张相同大小的空白黑色图像 empty = np.zeros([rows, cols, channels], np.uint8) # 然后开始遍历 # 首先遍历所有图像像素(边框除外) for i in range(int((filter_size - 1) / 2), rows - int((filter_size - 1) / 2)): for j in range(1, cols - int((filter_size - 1) / 2)): # 分通道取中值 for c in range(0, channels): # 用于计数:计当前计到了九宫格的第几个像素 count = 0 for k in range(i - int((filter_size - 1) / 2), i + int((filter_size - 1) / 2 + 1)): for m in range(j - int((filter_size - 1) / 2), j + int((filter_size - 1) / 2 + 1)): pixel_list[c][count] = src_img[k, m, c] count += 1 # 所有的赋值都结束后,再分通道取中值,并将其赋给空白图像中的对应位置 # 多通道 if channels != 1: for r in range(0, channels): # 按行排序 # 注意 pixel_list = np.sort(pixel_list, axis=1) empty[i, j, r] = pixel_list[r][int((filter_size * filter_size - 1) / 2)] else: # 单通道 empty[i, j] = pixel_list[int((filter_size * filter_size - 1) / 2)] # print(empty) return empty if __name__ == "__main__": cv.namedWindow("src", cv.WINDOW_NORMAL) cv.namedWindow("see", cv.WINDOW_NORMAL) cv.namedWindow("see1", cv.WINDOW_NORMAL) pathname = "E://Computer_Version//resource//4.png" src_img = cv.imread(pathname) cv.imshow("src", src_img) cv.imshow("see", median(src_img, 5,3)) # 与openCV自带函数进行对比 cv.imshow("see1", cv.medianBlur(src_img, 3)) cv.waitKey(0) cv.destroyAllWindows()
虽然效果不错,但是运行速度依旧堪忧,需要再多多改进
感谢大佬:[python,opencv]如何判断一副图片的通道数
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)