2017-10-01 3 views
1

J'essaie de mettre en œuvre manuellement un opérateur sobel.Squaring introduit beaucoup de bruit lorsque vous faites l'opérateur Sobel en utilisant filter2D (OpenCV)

Pour une raison quelconque, les composants horizontaux et verticaux de l'opérateur semblent avoir de bons résultats, mais l'image combinée a beaucoup de bruit.

Je remarque quand je fais quelque chose comme (imgv ** 2) ** 0.5, qui introduit également une tonne de bruit, même si idéalement, je devrais récupérer approximativement la même image.

Est-ce que quelqu'un sait ce qui se passe ici? Suis-je censé combiner les images d'une manière différente?

Voici mon code en 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 

Ceci est la sortie:

enter image description here

Répondre

3

Mise à jour: Méthode mieux.

#!/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) 

enter image description here


réponse originale:

Oui, il m'a troublé lorsque vous faites opération mathématique sur l'image OpenCV dans numpy. Le type de données d'image est np.uint8 par défaut. Donc, quand il peut débordement/débordement lors de l'opération mathématique si vous ne modifiez pas la percision.

Essayez ceci:

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() 

Colorful Sobel

Grayscale Sobel