It's not clear what do you mean by sorting, but looking at your code, it seems you want to find the median value of the pixels in an image. So I will answer this question.
For unsigned char
matrices (normal images, or in OpenCV format CV_8UC[1,2,3]
), you can use an old, but fery fast trick: a histogram.
- Calculate the histogram of your image
For each channel, start to sum the elements in the bins until their count is equal or above half the number of pixels in the image. The bin where you stop is the median element of your image
cv:Mat hist = cv::calcHist(image);
uchar * h = hist.data;
int sum = 0, bin = 0;
int maxElements = image.total();
while((sum < maxElements) && (bin < 255))
{
sum += h[bin];
}
std::cout << "Median pixel value of the image is " << bin << std::endl;
Because it does no sorting at all, and no copies of the original data, it is a lot faster than any other median-extraction algorithm.
I did not test the code, and it probably needs some checks, but you get the idea.
And if you want to sort a matrix of arbitrary data type, you should look into the sort functions provided by OpenCV. Check the docs :)
EDIT: there is an internal function getMedian
in align.cpp
//enum { LDR_SIZE = 256 };
int getMedian(Mat& img)
{
int channels = 0;
Mat hist;
int hist_size = LDR_SIZE;
float range[] = {0, LDR_SIZE} ;
const float* ranges[] = {range};
calcHist(&img, 1, &channels, Mat(), hist, 1, &hist_size, ranges);
float *ptr = hist.ptr<float>();
int median = 0, sum = 0;
int thresh = (int)img.total() / 2;
while(sum < thresh && median < LDR_SIZE) {
sum += static_cast<int>(ptr[median]);
median++;
}
return median;
}