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图是反的)
以上。
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图是反的)
以上。
相关文章推荐
- opencv的灰度变换使用及与自己实现的效果比较
- 自己写的mysql客户端应用程序(通过官方头文件和lib来编译链接实现)
- 写一函数,实现两个字符串的比较,即自己写一个strcmp函数
- 附两个自己认为比较重要的链接地址(移动端的position:fixed,flexbox实现垂直居中布局)
- OpenCV之imgproc 模块. 图像处理(2)实现自己的线性滤波器 给图像添加边界 Sobel 导数 Laplace 算子 Canny 边缘检测
- Lua 自己实现排序sort比较方法,抛出错误invalid order function for sorting
- CvSepFilter 用于opencv sobel算子实现
- OpenCV下利用傅里叶变换和逆变换实现图像卷积算法,并附自己对于卷积核/模板核算子的理解!
- 用C++(OpenCV)自己实现彩色直方图均衡化
- Sobel算子理论及openCV实现代码
- 摘要:我们经常会用到递归函数,但是如果递归深度太大时,往往导致栈溢出。而递归深度往往不太容易把握,所以比较安全一点的做法就是:用循环代替递归。文章最后的原文里面讲了如何用10步实现这个过程,相当精彩。本文翻译了这篇文章,并加了自己的一点注释和理解。
- 系统递归和自己用栈实现递归的比较
- 【OpenCV】Sobel算子理论与OpenCV代码实现
- openCV2马拉松第19圈——Harris角点检测(自己实现)
- 利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较)
- [C#]简单重写IComparer接口,实现自己的String.CompareTo 方法,自定义比较规则。
- uva 101 - The Blocks Problem 练习代码控制能力的题目吧 ,思路转化为代码,实现自己的比较复杂的想法
- OpenCv图像差分(算法自己实现)
- 图像处理算法基础(六)---sobel算子自实现与opencv对比
- 自己写的jQuery实现下拉列表,有事件冒泡,带有比较详细的注释