【OpenCV-Python】关于Python中OpenCV的图像格式问题以及图像遍历问题

一开始学习OpenCV是用的C++,但是由于后面课程原因,以及后来学习深度学习相关需要用到python,发现了opencv在各种语言下的一些差异。在这里记录一下所遇到的一些问题~

关于图像读入的问题

路径中含中文的解决方式

在用imread读入图像时,若是路径中含有中文,则会出现错误error: (-215:Assertion failed) !_src.empty(),即并没有成功读入~
所以重写一个cv_imread函数,调用后就解决了~

def cv_imread(filepath):
    cv_img = cv2.imdecode(np.fromfile(filepath, dtype=np.uint8), cv2.IMREAD_COLOR)
    return cv_img

读入后图像的格式

与C++和JAVA中用Mat格式存储图像不同,在Python中,用的是numpy的数组,即存储的。我们可以用numpy数组的shape属性来查看一下这张图片的长宽和维度~

src = cv_imread(filepath)  # 打开一张图片
print(src.shape)
#输出(78, 67, 3)

在C++和Java中,我们一般用Mat.row()Mat.col()来获取行数和列数;而在Python中,得用src.shape[0]src.shape[1]来获取行数和列数。
当然,知道图像是numpy数组类型还不够,因为之前在尝试最基础的卷积操作时遇到了点儿问题…就是用numpy.zero函数pre-alloate了一个输出,然后让卷积核的长宽为一,输出的居然和源图像不一样!后面才注意到应该是dtype的问题,对于输入的OpenCV图像,dtype='uint8',所以在预分配时,数组的dytpe设置为uint8格式,问题就解决了~
一开始还怀疑卷积函数写错了,后面觉得不应该啊…而且输入和输出中每个值都是一样的…最后的卷积代码如下:

def conv(img, ker):
    oh=img.shape[0] - ker.shape[0] + 1
    ow=img.shape[1] - ker.shape[1] + 1
    res = np.zeros([ oh, ow ],dtype='uint8')
    for h in range(oh): 
        for w in range(ow):
            res[ hi , wi] = (img[h:h + ker.shape[0], w:w + ker.shape[1]]).sum()
    return res  

不过呢,这样的话,最大值就只有255了,完全不足以解决问题,所以呢,真的要进行卷积操作还是不要这样设置dtype了。
此处就全当作说明一下图像的格式吧~

关于图像处理过程中的一些小问题

由于项目原因,想要遍历图像,用了for循环嵌套,发现速度实在太慢了,感觉很不合理…
后来上网查找原因,应该是python中for循环速度比较慢,然后看到两个解决方法。一个是用Numba,一个可以将 Python 代码转换为优化过的机器代码的编译库,但是本人暂时还没有尝试该方法,到时候尝试了来补充上;另一个方法是直接调用numpy中自带的函数,这个就要看情况发挥啦~
更改之后,速度就起飞了!
但不得不说,这方面确实还是Java和C++比较爽啊…
附上自己解决问题的代码

这个是获取二值化图像中每一列白色像素的个数:

rc=np.where(binary=0) #获得一个二维元组
pix=np.zeros(binary.shape[1])
for c in rc[1]:
    pix[c]+=1

这个呢是在获取灰度图像中每一列灰度值的和。因为行的和用sum就能获取,所以这里就用了个转置。不过或许有更合理的解决办法呢~

#print(gray.transpose())
gt=gray.transpose()
dense=np.zeros(gt.shape[0])
for i in range(gt.shape[0]):
    dense[i]=np.sum(gt[i])

小结

就先记录到这里。虽然说现在python的库调用起来确实非常便捷,但在某些方面好像还是Java和C++的性能更好一点呢~

你可能感兴趣的:(OpenCV,Python,python,opencv)