我们在获取显著性检测时,我们希望进行无监督提取或者分割目标。深度学习在目标检测与显著性检测方面已经是非常成熟了,但是算法复杂度相对于传统无监督的算法来说还是高了点,这里只是写个示例。仅供参考。
其中:
关于均值漂移 cv2.pyrMeanShiftFiltering
import cv2
import numpy as np
import matplotlib.pyplot as plt
def show_calculate(name, img_hist):
plt.plot(img_hist)
plt.title(name)
plt.xlabel('Bins')
plt.ylabel('Pixels')
plt.show()
# 反向投影
def backproject(source, levels=2, scale=1):
hsv = cv2.cvtColor(source, cv2.COLOR_BGR2HSV)
hsvt = hsv.copy()
# cv2.imshow("hsvt",hsvt)
roihist = cv2.calcHist([hsv], [0, 1], None, [levels, levels], [0, 180, 0, 256])
cv2.normalize(roihist, roihist, 0, 255, cv2.NORM_MINMAX)
# show_calculate("roihist", roihist)
dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256], scale)
return dst
def saliency_by_backprojection(img):
cv2.pyrMeanShiftFiltering(img, 2, 10, img, 4)
backproj = np.uint8(backproject(img, levels = 2))
# cv2.imshow("backproj",backproj)
cv2.normalize(backproj,backproj,0,255,cv2.NORM_MINMAX)
saliencies = [backproj, backproj, backproj]
saliency = cv2.merge(saliencies)
# cv2.imshow("saliency",saliency)
cv2.pyrMeanShiftFiltering(saliency, 20, 200, saliency, 2)
# cv2.imshow("pyrMeanShiftFiltering1", saliency)
saliency = cv2.cvtColor(saliency, cv2.COLOR_BGR2GRAY)
cv2.equalizeHist(saliency, saliency)
# cv2.imshow("equalizeHist", saliency)
saliency = 255 - saliency
(_, saliency) = cv2.threshold(saliency, 200, 255, cv2.THRESH_BINARY)
# cv2.imshow("threshold", saliency)
return saliency
def refine_saliency_with_grabcut(img, saliency):
_, contours, hierarchy = cv2.findContours(saliency, cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea)
rect = cv2.boundingRect(contours[-1])
bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)
saliency[np.where(saliency > 0)] = cv2.GC_FGD
mask = saliency
cv2.grabCut(img, mask, rect, bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_RECT)
mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
return mask
def backprojection_saliency(img):
saliency = saliency_by_backprojection(img)
mask = refine_saliency_with_grabcut(img, saliency)
return img * mask[:, :, np.newaxis]
if __name__ == "__main__":
img = cv2.imread("./images/flower.jpg")
img = cv2.resize(img, (640//2, 480//2))
segmentation = backprojection_saliency(img)
cv2.imshow("original", img)
cv2.imshow("segmentation", segmentation)
cv2.waitKey(0)
cv2.destroyAllWindows()
反向投影直方图量化运行效果:
代码运行时效果:
原图与效果图: