OpenCV meanShiftFiltering example source code ( cpu: pyrMeanShiftFiltering, gpu:meanShiftFiltering, gpu:meanShiftSegmentation )

'meanshift' is clustering algorithm. It can be used color segmentation, color tracking..
This article is about color segmentation using meanShiftFiltering function in the opencv.

There are 2 example of cpu, gpu version in the source code.
Note, the input image in the gpu version must be 8uc4 type.

please refer to this page for input parameter.
and this webpage -> http://seiya-kumada.blogspot.kr/2013/05/mean-shift-filtering-practice-by-opencv.html

thank you.

#include < time.h>   
#include < opencv2\opencv.hpp>   
#include < opencv2\gpu\gpu.hpp>   
#include < string>   
#include < stdio.h>   
#ifdef _DEBUG           
#pragma comment(lib, "opencv_core249d.lib")   
#pragma comment(lib, "opencv_imgproc249d.lib")   //MAT processing   
#pragma comment(lib, "opencv_gpu249d.lib")   
#pragma comment(lib, "opencv_highgui249d.lib")   
#pragma comment(lib, "opencv_core249.lib")   
#pragma comment(lib, "opencv_imgproc249.lib")   
#pragma comment(lib, "opencv_gpu249.lib")   
#pragma comment(lib, "opencv_highgui249.lib")   

using namespace cv;
using namespace std;

void ProccTimePrint( unsigned long Atime , string msg)   
 unsigned long Btime=0;   
 float sec, fps;   
 Btime = getTickCount();   
 sec = (Btime - Atime)/getTickFrequency();   
 fps = 1/sec;   
 printf("%s %.4lf(sec) / %.4lf(fps) \n", msg.c_str(),  sec, fps );   

void main()
 unsigned long AAtime=0;
 //image load
 Mat img = imread("image2.jpg");
 Mat outImg, outimg2;

 //cpu version meanshift
 AAtime = getTickCount();
 pyrMeanShiftFiltering(img, outImg, 30, 30, 3);
 ProccTimePrint(AAtime , "cpu");

 //gpu version meanshift
 gpu::GpuMat pimgGpu, imgGpu, outImgGpu;
 AAtime = getTickCount();
 //gpu meanshift only support 8uc4 type.
 gpu::cvtColor(pimgGpu, imgGpu, CV_BGR2BGRA);
 gpu::meanShiftFiltering(imgGpu, outImgGpu, 30, 30);
 ProccTimePrint(AAtime , "gpu");

 //show image
 imshow("origin", img);
 imshow("MeanShift Filter cpu", outImg);
 imshow("MeanShift Filter gpu", outimg2);



Below source code is about gpu::meanShiftSegmentation.
In this function, we can set minimum segment size of pixel count.
The smaller segments are merged.

Mat outImg3;
 AAtime = getTickCount();
 gpu::meanShiftSegmentation(imgGpu, outImg3, 30, 30, 300);
 ProccTimePrint(AAtime , "gpu segment");
 imshow("MeanShift segmentation gpu", outImg3);

Related contents k-means


yuv422(YUYV) to RGB and RGB to yuv422(YUYV), (Using OpenCV and TBB)

In past, I wrote an articel about YUV 444, 422, 411 introduction and yuv <-> rgb converting example code.
refer to this page -> http://feelmare.blogspot.kr/2012/11/yuv-color-format-444-422-411-simple.html

In this article, I will introduce method of using opencv and TBB.
TBB is an acronym for Thread Building Block.
TBB is to enable parellel processing using multi thread.
see the this page -> http://feelmare.blogspot.kr/2014/12/opencv-tbb-utility-parallelfor.html

This is YUV422 to RGB example source code.
In my case YUV422 is consisted of YUYV.
And input type of the YUYV data is unsigned char *.

So example is
unsigned char * yuyv to Mat rgb
In here, m_stride is real width length of yuyv data.

Mat yuyv(m_height, m_width, CV_8UC2);
memcpy( yuyv.data, yuyv_buffer, sizeof(unsigned char) * (m_stride * m_height) );
Mat rgb(m_height, m_width, CV_8UC3);
cvtColor(yuyv, rgb, CV_YUV2BGR_YUYV);

Next example is rgb to yuyv using TBB.
class Parallel_process : public cv::ParallelLoopBody

 cv::Mat& inImg;
 unsigned char* outImg;
 int widhStep;
 int m_stride;

 Parallel_process(cv::Mat& inputImgage,  unsigned char* outImage)
  : inImg(inputImgage), outImg(outImage){

   widhStep = inputImgage.size().width * 3; 
   m_stride = inputImgage.size().width *2;


 virtual void operator()(const cv::Range& range) const
  for(int i = range.start; i < range.end; i++)

   int s1 = i*widhStep;

   for(int iw=0; iw< inImg.size().width; iw=iw+2)
    int s2 = iw*3;

    int mc = s1+s2;
    int B1 = (unsigned char)(inImg.data[mc + 0]);
    int G1 = (unsigned char)(inImg.data[mc + 1]);
    int R1 = (unsigned char)(inImg.data[mc + 2]);
    int B2 = (unsigned char)(inImg.data[mc + 3]);
    int G2 = (unsigned char)(inImg.data[mc + 4]);
    int R2 = (unsigned char)(inImg.data[mc + 5]);

    int Y = (0.257*R1) + (0.504*G1) + (0.098*B1) +16;
    int U = -(0.148*R1) - (0.291*G1) + (0.439*B1) + 128;
    int V = (0.439*R1 ) - (0.368*G1) - (0.071*B1) + 128;
    int Y2 = (0.257*R2) + (0.504*G2) + (0.098*B2) +16;

    Y = MMIN(255, MMAX(0, Y));
    U = MMIN(255, MMAX(0, U));
    V = MMIN(255, MMAX(0, V));
    Y2 = MMIN(255, MMAX(0, Y2)); 

    mc = i*m_stride + iw*2;
    outImg[mc + 0] = Y;
    outImg[mc + 1] = U;
    outImg[mc + 2] = Y2;
    outImg[mc + 3] = V;


//in main rutine
cv::parallel_for_(cv::Range(0, (OriginMat).rows), Parallel_process((OriginMat), inP_OriginImg));


In opencv convert function,  YUYV to RGB option is exist (-> CV_YUV2BGR_YUYV).
But RGB to YUYV option is not exist.

thank you.


OpenCV TBB utility ( parallel_for, ParallelLoopBody )

see the this page

I will upload another processing example soon.

thank you.