使用filter2D(OpenCV)做Sobel运算符时,平方会引入很多噪声 [英] Squaring introduces a lot of noise when doing Sobel operator using filter2D (OpenCV)

查看:280
本文介绍了使用filter2D(OpenCV)做Sobel运算符时,平方会引入很多噪声的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试手动实施sobel运算符.

I am trying to manually implement a sobel operator.

由于某种原因,操作员的水平和垂直分量似乎都具有良好的效果,但是组合后的图像有很多噪点.

For some reason, the horizontal and vertical components of the operator seem to have good results, but the combined image has a lot of noise.

我注意到,当我执行(imgv ** 2)** 0.5之类的操作时,也会引入大量噪声,即使理想情况下,我也应该获得大致相同的图像.

I notice when I do something like (imgv**2)**0.5, that also introduces a ton of noise, even though ideally, I should get approximately the same image back.

有人知道这是怎么回事吗?我应该以其他方式组合图像吗?

Does anyone know what's going on here? Am I supposed to combine the images a different way?

这是我在python中的代码:

Here is my code in python:

import cv2
import numpy as np

sobelX = np.array([[1,0,-1],[2,0,-2],[1,0,-1]])
sobelY = sobelX.T

imgoriginal = cv2.imread("building.bmp") 

imgv = cv2.filter2D(imgoriginal, -1, sobelY)
imgh = cv2.filter2D(imgoriginal, -1, sobelX)
imgboth = (imgv**2 + img**2)**0.5

这是输出:

推荐答案

更新:一种更好方法.

#!/usr/bin/python3
# 2017.12.22 21:48:22 CST

import cv2
import numpy as np

## parameters
sobelX = np.array([[1,0,-1],[2,0,-2],[1,0,-1]])
sobelY = sobelX.T
ddepth = cv2.CV_16S

## calc gx and gy
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.GaussianBlur(img, (3,3), 0)
gx = cv2.filter2D(img, ddepth, sobelX)
gy = cv2.filter2D(img, ddepth, sobelY)

## calc gridxy 
gxabs = cv2.convertScaleAbs(gx)
gyabs = cv2.convertScaleAbs(gy)
grad = cv2.addWeighted(gxabs, 0.5, gyabs, 0.5, 0)

cv2.imwrite("result.png", grad)

原始答案:

是的,当对numpy中的opencv图像进行数学运算时,这给我带来了麻烦.图像数据类型默认为 np.uint8 .因此,如果不更改精度,在进行数学运算时可能上溢/下溢.

Yeah, it has troubled me when doing math operation on the opencv image in numpy. The image data type is np.uint8 defaultly. So, when it may overflow/underflow when doing math operation if you don't change the percision.

尝试一下:

import cv2
import numpy as np

sobelX = np.array([[1,0,-1],[2,0,-2],[1,0,-1]])
sobelY = sobelX.T

img = cv2.imread("cat.png")

## Change the color space
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

imgv = cv2.filter2D(img, -1, sobelY)
imgh = cv2.filter2D(img, -1, sobelX)

## Change the percision first, then do math operation
imghv = (np.float32(imgv)**2 + np.float32(img)**2)**0.5
#imghv = (np.float32(imgv)**2 + np.float32(img)**2)**0.5

## Normalize and change the percision
## Use cv2.convertScaleAbs() to convert value into the right range [0, 255]
imghv = imghv/imghv.max()*255
imghv = cv2.convertScaleAbs(imghv) 

## Display
res = np.hstack((imgh, imgv, imghv))
cv2.imshow("Sobel", res)
cv2.waitKey()
cv2.destroyAllWindows()

这篇关于使用filter2D(OpenCV)做Sobel运算符时,平方会引入很多噪声的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆