MeanShift algorithm
Mean shift
is a machine learning algorithm that is not limited to applications on images. AboutMean shift
There are many books and articles that introduce algorithms, so I won't go into them here. In brief.Meanshift
The algorithm is an iterative algorithm that needs to be given an initial region, and then this algorithm iteratively adjusts this region so that it best matches our desired features.
There are two places in OpenCV that use the Mean Shift
. Separately:
pyrMeanShiftFiltering
meanShift
Only the use of the second function is described here.
Our original image is the same sunflower image as last time, and we select one of the sunflowers to calculate the Histogram, but this time we calculate the Histogram for the Hue channel:
This histogram data is later used to find sunflowers in another image using the Meanshift algorithm.
Here is the code, first load the original image. Find the sunflower in the original image and calculate the Histogram of the sunflower region.
cv::Mat image = cv::imread("D:\\\ Sunflower.jpg"); cv::Mat imageROI = image(cv::Rect(130, 250, 75, 75)); ColorHistogram hist; cv::Mat h = (imageROI, 65); cv::imshow("pic", image); ContentFinder finder; (h); (-1.0f);
After that load the image we want to detect and do backproject to get the probability distribution plot.
cv::Mat image2 = cv::imread("D:\\"); cv::Mat hsv; cv::cvtColor(image2, hsv, CV_BGR2HSV); int ch[1] = {0}; cv::Mat probImage = (hsv, 0.0, 180, ch); cv::Mat img_color; cv::applyColorMap(probImage, img_color, cv::COLORMAP_JET); cv::imshow("backproject", img_color);
In the end Meanshift is all about finding the region with the highest probability in the graph on the right. For this problem, it's really just a matter of doing an iteration.
meanshift is more efficient than traversal. However, if the initial region is not well chosen, you may not find the region where the sunflower is located.
So meanshift isn't everything.
cv::Rect rect(100, 100, 200, 200); cv::rectangle(image2, rect, cv::Scalar(255,0,0)); // cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER, 30, 1); cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 10, 1); cv::meanShift(probImage, rect, criteria); cv::rectangle(image2, rect, cv::Scalar(0,0,255)); cv::imshow("image2", image2);
Here is the output, the blue box is the initial area we randomly selected, and the red box is the result obtained. You can see that the sunflower area was accurately found.
If we don't pick the initial area very well, we won't be able to find the sunflower. For example, the following code.
cv::Rect rect(0, 0, 200, 200); cv::rectangle(image2, rect, cv::Scalar(255,0,0)); cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 10, 1); cv::meanShift(probImage, rect, criteria); cv::rectangle(image2, rect, cv::Scalar(0,0,255)); cv::imshow("image2", image2);
You can see that the iteration was done 10 times, but the region didn't move at all. Generally we can randomly select the initial region, and if one region meanshift fails, then randomly select another region. This way we can get good results after a few tries.
The above is OpenCV machine learning MeanShift algorithm notes to share the details, more information about OpenCV machine learning please pay attention to my other related articles!