图像处理相关函数
skimage图像处理的坑:
1.在编程调试过程中,如果图片位深超过8位,则OpenCV无法正常显示,发现skimage处理后(如canny检测)的数据都会转换成uint32类型的数据,而OpenCV的图片显示函数则不能正常显示uint32类型的numpy数组,因此,可以调用下面的函数来重新编码,从而可以在OpenCV中显示图片。
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_ski_canny = feature.canny(gray,1.3,0.05,0.20)
img_ski_canny = np.uint8(cv2.normalize(img_ski_canny.astype(int),img_ski_canny.astype(int),0,255,norm_type=cv2.NORM_MINMAX))
cv2.imshow('ski_result',img_ski_canny)
cv2.waitKey(0)
2.如果需要将数组重新整形为指定格式可以用下面这个代码。
import cv2 from skimage import feature,io from matplotlib import pyplot as plt from service import IMAGE import numpy as np rw = IMAGE() img_path = 'data/zh1.jpg' img_data = rw.read_img(img_path)[-1] img_data = np.swapaxes(img_data,0,1) img_data = np.swapaxes(img_data,1,2) # 转换轴 img_data = np.flip(img_data,axis=2) # 转换波段
img_data = img_data[:,:,1:]
img_data = np.uint8(cv2.normalize(img_data,img_data.copy(),0,255,norm_type=cv2.NORM_MINMAX)) # 显示多波段图片,此处是先标准化,在转换为uint8,此时便可以在OpenCV中显示
3.OpenCV中显示用skimage的canny检测后的结果,需要将bool型数据转换为0-1类型的数据,然后对其进行转换为0和255数据,才能够在imshow中正常显示(可能由于skimage处理输出的数据都是uint8类型的??)
np.uint8(np.where(edge!=0,255,0))
4.图像处理中如果需要提取边缘(内边)的话,可以用二值化图减去腐蚀一个像素后的图像,从而得到内部边缘(即所有边缘点像素都在目标内部)。
# 边缘端点检测 edge = np.subtract(mask_temp, morphology.erosion(mask_temp,selem=morphology.square(3))) # 提出内边缘 edge_coords = np.argwhere(edge == 1) # 获取索引