您的位置:首页 > 运维架构

opencv的sobel算子(自己实现与官方比较)

2016-11-26 01:09 190 查看
做了sobel的实现,比较现有函数,发现自己的问题。

3*3的sobel为:[[1,2,1],[0,0,0],[-1,-2,-1]]/8和它的转置矩阵。

为什么除以8不是4呢,我猜是因为隐含了(求导1+求导2)/2的变换。比如3*3的图形,求正中间像素的梯度,有[(A[0][1]-A[1][1])+(A[1][1]-A[2][1])]/2。

所以得出整体除以8作为梯度值。

视线中的问题和学到的:1、cv2.filter2D做的其实是相关,不是卷积

    2、用astype做负浮点数的变换(到np.uint8),会做类似缩放,把整个二维数组映射到(-255,255)

    3、导致cv2.Sobel是灰的,我的图是黑白。。。

所以,我把sobel算子和原图做了相关后,加了128,这样和官方的效果差不多了。不过y图的好像反了,不过关系不大。

代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
pic=cv2.imread("C:\\Users\\acer\\Pictures\\book.jpg")
pic_float=pic.astype(np.float)
pic1=cv2.cvtColor(pic, cv2.COLOR_RGB2GRAY)

edge=cv2.Canny(pic1,80,170)
#cv2.imshow("GRAY",pic1)
#cv2.imshow("EDGE",edge)
pic1=pic1.astype(np.float)
sobelx=cv2.Sobel(pic1,cv2.CV_64F,1,0,ksize=3)
sobely=cv2.Sobel(pic1,cv2.CV_64F,0,1,ksize=3)

kernel=np.array([[1.0,2.0,1.0],[2.0,4.0,2.0],[1.0,2.0,1.0]])/16
kernelx=np.array([[-1.0,0.0,1.0],[-2.0,0.0,2.0],[-1.0,0.0,1.0]])/8
kernely=np.array([[1.0,2.0,1.0],[0.0,0.0,0.0],[-1.0,-2.0,-1.0]])/8
pic1=cv2.filter2D(pic1,-1,kernel)
my_sobelx=cv2.filter2D(pic1,-1,kernelx)+128
my_sobely=cv2.filter2D(pic1,-1,kernely)+128

my_sobelx=my_sobelx.astype(np.uint8)
my_sobely=my_sobely.astype(np.uint8)

plt.subplot(2,2,1)
plt.imshow(sobelx,cmap='gray')
plt.title('X'),plt.xticks([1,2]),plt.yticks([3,4])
plt.subplot(2,2,2)
plt.imshow(sobely,cmap='gray')
plt.title('Y'),plt.xticks([]),plt.yticks([])
plt.subplot(2,2,3)
plt.imshow(my_sobelx,cmap='gray')
plt.title('MY_X'),plt.xticks([1,2]),plt.yticks([3,4])
plt.subplot(2,2,4)
plt.imshow(my_sobely,cmap='gray')
plt.title('MY_Y'),plt.xticks([]),plt.yticks([])

plt.show()

错的图(没加128)



改正后的图(放大一部分,清楚点,y图是反的)



以上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图像
相关文章推荐