Example source code of K-means algorithm in OpenCV,
The source code are two version, one is python and other is C++.
And I compare processing time, I do same condition such as same image, same parameter, and I checked same result.
The winner of processing speed is C++.
Despite C++ contain many "for" syntax but faster than python.
Check example source code.
This is input image
C++ version.
...
#include < stdio.h>
#include < iostream>
#include < opencv2\opencv.hpp>
#ifdef _DEBUG
#pragma comment(lib, "opencv_core247d.lib")
#pragma comment(lib, "opencv_imgproc247d.lib") //MAT processing
#pragma comment(lib, "opencv_highgui247d.lib")
#else
#pragma comment(lib, "opencv_core247.lib")
#pragma comment(lib, "opencv_imgproc247.lib")
#pragma comment(lib, "opencv_highgui247.lib")
#endif
using namespace cv;
using namespace std;
void main()
{
unsigned long AAtime=0, BBtime=0; //check processing time
unsigned long inAtime=0, inBtime=0;
AAtime = getTickCount(); //check processing time
inAtime = getTickCount(); //check processing time
Mat src = imread( "mare-08.jpg", 1 );
Mat samples(src.rows * src.cols, 3, CV_32F);
for( int y = 0; y < src.rows; y++ )
for( int x = 0; x < src.cols; x++ )
for( int z = 0; z < 3; z++)
samples.at< float>(y + x*src.rows, z) = src.at< Vec3b>(y,x)[z];
inBtime = getTickCount(); //check processing time
printf("in Data preparing %.2lf sec \n", (inBtime - inAtime)/getTickFrequency() ); //check processing time
inAtime = getTickCount(); //check processing time
int clusterCount = 5;
Mat labels;
int attempts = 10;
Mat centers;
kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 1.0), attempts, KMEANS_RANDOM_CENTERS, centers );
inBtime = getTickCount(); //check processing time
printf("K mean processing %.2lf sec \n", (inBtime - inAtime)/getTickFrequency() ); //check processing time
inAtime = getTickCount(); //check processing time
Mat new_image( src.size(), src.type() );
for( int y = 0; y < src.rows; y++ )
{
for( int x = 0; x < src.cols; x++ )
{
int cluster_idx = labels.at< int>(y + x*src.rows,0);
new_image.at< Vec3b>(y,x)[0] = centers.at< float>(cluster_idx, 0);
new_image.at< Vec3b>(y,x)[1] = centers.at< float>(cluster_idx, 1);
new_image.at< Vec3b>(y,x)[2] = centers.at< float>(cluster_idx, 2);
}
}
inBtime = getTickCount(); //check processing time
printf("out Data Preparing processing %.2lf sec \n", (inBtime - inAtime)/getTickFrequency() ); //check processing time
BBtime = getTickCount(); //check processing time
printf("Total processing %.2lf sec \n", (BBtime - AAtime)/getTickFrequency() ); //check processing time
//imshow( "clustered image", new_image );
imwrite("clustered_image.jpg", new_image);
//waitKey( 0 );
}
...
result image and processing time of C++ version
Python Version
...
import numpy as np
import cv2
from matplotlib import pyplot as plt
e1 = cv2.getTickCount()
inA = cv2.getTickCount()
img = cv2.imread('mare-08.jpg')
Z = img.reshape((-1,3))
# convert to np.float32
Z = np.float32(Z)
inB = cv2.getTickCount()
print("in data preparing", (inB-inA)/cv2.getTickFrequency())
# define criteria, number of clusters(K) and apply kmeans()
inA = cv2.getTickCount()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 5
ret,label,center = cv2.kmeans(Z,K,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
inB = cv2.getTickCount()
print("K-means ", (inB-inA)/cv2.getTickFrequency())
# Now convert back into uint8, and make original image
inA = cv2.getTickCount()
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
inB = cv2.getTickCount()
print("out data preparing", (inB-inA)/cv2.getTickFrequency())
#print(center)
#print(label)
e2 = cv2.getTickCount()
time = (e2 - e1)/cv2.getTickFrequency()
print("total time", time, 1/time)
cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
...
The result of python