我想确定在Python 3脚本中使用OpenCV哪种2色相值最能代表一幅图像。 到目前为止,我已经能够访问色相通道并显示其色相直方图:
如您所见,基本上有两种不同色调的像素,米色和绿色。
我已按如下方式访问色相频道:
hsv = cv.cvtColor( self.img, cv.COLOR_BGR2HSV )
hue,sat,val = cv.split(hsv)
在色调通道上进行操作以确定最适合表示图像的两个色调值的最有效方法是什么?
编辑#2快到了,但仍然需要帮助:
我整理了一些代码,以使用OpenCV kmeans将图像转换为2种颜色:
import numpy as np
import cv2
import time
import sys
img = cv2.imread('3.JPG')
cv2.imshow('Original',img)
print (sys.version)
if sys.version_info[0] < 3:
raise Exception("Python 3 or a more recent version is required.")
def redo():
Z = img.reshape((-1,3))
# convert to np.float32
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2
start_time = time.time()
ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
end_time = time.time()
print("Elapsed time was %g seconds" % (end_time - start_time))
# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv2.imshow('Converted',res2)
while(1):
ch = cv2.waitKey(50)
if ch == 27:
break
if ch == ord(' '):
redo()
cv2.destroyAllWindows()
仍需要:
答案 0 :(得分:0)
我已经解决了您在帖子中提到的一些事情。
您不需要回退到uint8。中心是大小为(2,3)的数组,其中行是您的中心点(例如色相),列是每种色相的BGR值。
我已切换到Scipy KMeans2,而不是使用OpenCVs实现。在与OpenCV相同的图像上,速度似乎要快3倍。
import numpy as np
from scipy.cluster.vq import kmeans, kmeans2
import time, sys, cv2
img = cv2.imread('3.jpg')
print (sys.version)
if sys.version_info[0] < 3:
raise Exception("Python 3 or a more recent version is required.")
def redo():
Z = img.reshape((-1,3))
Z = np.float32(Z)
# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2
start_time = time.time()
ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
end_time = time.time()
print("Elapsed cv2 time was %g seconds" % (end_time - start_time))
print("center")
print(center)
start_time = time.time()
spcenter, splabel = kmeans2(Z,K,10,1,'points','warn',False)
end_time = time.time()
print("Elapsed scipy time was %g seconds" % (end_time - start_time))
print("center")
print(spcenter)
print("diff")
check = np.abs(spcenter[0][0]-center[0][0])
checkflip = np.abs(spcenter[0][0]-center[1][0])
if (check < checkflip):
print(np.abs(spcenter-center))
else:
print("labels are flipped, has no effect on data")
print(np.abs(spcenter-np.roll(center,1,0)))
# Now convert back into uint8, and make original image
#center = np.uint8(center)
res = spcenter[splabel.flatten()]
res2 = res.reshape((img.shape))
cv2.imwrite('converted.jpg',res2)
redo()
您可能无法比此代码给您提供任何计时都更好。如果可以解决问题,则可以尝试缩小图像。这样可以加快处理速度。
另一个解决方案,如我提到的,正在转向一种更快的语言,例如C。我可以尝试一下,但是我不确定您正在使用什么其他代码以及它是否可以工作。让我知道您是否想走这条路。