이 이미지에서 흰색 줄무늬를 추출하고 있지만 'Lab'이미지에서 기본 Sobel 연산자의 출력을보고 싶었습니다. 검은 색 줄무늬가 원하는 결과를 보게되어 기쁘지만 'np.hstack'연산자 뒤에서 무슨 일이 벌어지고 있는지 정당화 할 수 없습니다. plt.imshow ()가 'sobel'에만 적용되면 동일한 출력을 얻지 못합니다. 원하는 출력은 흰색 줄무늬가 포함 된 이진 이미지입니다.
import numpy as np
import cv2
import os,sys
from matplotlib import pyplot as plt
def getColorSpaces(image):
rgb = cv2.cvtColor(image,cv2.COLOR_RGB2BGR)
gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
return rgb,gray
def getImageDimnesion(image):
height,width = image.shape[:2]
return height,width
def showImage(image,title,cmap):
plt.imshow(image,cmap=cmap)
plt.axis('off')
plt.title(title)
def splitRGBChannels(image):
red, green, blue= cv2.split(img)
return red, green, blue
def getMagnitude(gray):
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
abs_sobelx = np.absolute(sobelx)
abs_sobely = np.absolute(sobely)
magnitude=np.sqrt(abs_sobelx*abs_sobelx+abs_sobely*abs_sobely)
return magnitude,np.arctan2(abs_sobely,abs_sobelx)
def applySobel(gray):
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
abs_sobelx = np.absolute(sobelx)
abs_sobely = np.absolute(sobely)
return abs_sobelx+abs_sobely
images_path=r'images'
images=os.listdir(images_path)
for im in images[:]:
print(im)
img = cv2.imread(os.path.join(images_path,im))
plt.axis('off')
plt.title('Originial')
plt.imshow(img,cmap='gray')
plt.show()
for im in images[:]:
print(im)
plt.figure(figsize=(12, 12))
img = cv2.imread(os.path.join(images_path,im))
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lab=cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
h,s,v = cv2.split(hsv)
l,a,b = cv2.split(lab)
sobel=applySobel(lab)
imgs_comb = np.hstack([img,lab,sobel])
plt.axis('off')
plt.title('Originial-Lab-Sobel')
plt.imshow(imgs_comb,cmap='gray')
plt.show()
편집 1
plt.axis('off')
plt.title('img')
plt.imshow(img,cmap='gray')
plt.show()
plt.axis('off')
plt.title('lab')
plt.imshow(lab,cmap='gray')
plt.show()
plt.axis('off')
plt.title('sobel')
plt.imshow(sobel,cmap='gray')
plt.show()
plt.axis('off')
plt.title('hstack')
plt.imshow(imgs_comb,cmap='gray') #<<<<<Different output but is generic when tried with different images
plt.show()
Your applySobel
method expects a grey scale (single channel) image as input, but you are using lab
(3-channel image) as input, which will apply Sobel-filtering to all 3 channels. The unexpected result comes from plt.imshow
interpreting the Sobel-filtered Lab-channels as the RGB-channels of your image.
It works as intended if you only use l
, a
or b
instead (or a different method to convert Lab to grey). However, the result will not be binary. To make it binary, you can apply a threshold (using cv2.threshold(img, threshold, max_value, cv2.THRESH_BINARY)
. Here is an example:
import cv2
import numpy as np
from matplotlib import pyplot as plt
from skimage.io import imread
def applySobel(gray):
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
abs_sobelx = np.absolute(sobelx)
abs_sobely = np.absolute(sobely)
return abs_sobelx + abs_sobely
# Load the image (RGB)
img = imread('https://i.stack.imgur.com/qN2ta.jpg')
# Convert to Lab and split channels
lab = cv2.cvtColor(img, cv2.COLOR_RGB2LAB)
l, a, b = cv2.split(lab)
# Plot image of Lab-channels
plt.title('L, a, and b channel')
plt.imshow(np.hstack([l, a, b]), cmap='gray')
plt.show()
# Apply Sobel to L-channel (the other channels have low contrast)
l_sobel = applySobel(l)
# Plot result
plt.title('Sobel-filtered L-channel')
plt.imshow(l_sobel, cmap='gray')
plt.show()
# Make result binary by applying a threshold
sobel_thresh = np.uint8(cv2.threshold(l_sobel, 500, 255, cv2.THRESH_BINARY)[1])
# Plot binary result
plt.title('Thresholded Sobel-filtered L-channel')
plt.imshow(sobel_thresh, cmap='gray')
plt.show()
This results in the following images:
The Sobel filter is used for edge detection, so it will only highlight the edges instead of the whole stripes. So if your goal is to highlight the whole stripes, directly thresholding the L-channel would be more effective:
# Directly threshold L-channel and plot
plt.imshow(cv2.threshold(l, 220, 255, cv2.THRESH_BINARY)[1], cmap='gray')
plt.show()
Result:
또한 np.hstack
차원이 다르기 때문에 3 채널 이미지를 그레이 스케일 / 이진 이미지와 직접 결합 하는 데 사용할 수 없습니다 . 먼저 np.stack((img,) * 3, axis=-1)
단일 채널 이미지를 3 채널 이미지로 변환 하는 데 사용 합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다