1.OpenCV自带的CamShift算法(例程)解读:
    https://blog.csdn.net/kilotwo/article/details/89053311?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

    CamShift使用的算法(Mean Shift)原理解读:
    https://blog.csdn.net/zhjm07054115/article/details/24669145

    2.首先,Camshift一般使用彩色直方图进行匹配,而红外视频为灰度图像,所以我们需要进行图像的转换。
    一般彩色RGB到灰度图像转换公式如下:
    Gray = R0.299 + G0.587 + B0.114
    而实际应用时,希望避免低速的浮点运算,所以需要整数算法。
    注意到系数都是3位精度,我们可以将它们缩放1000倍来实现整数运算算法:
    Gray = (R
    299 + G587 + B114 + 500) / 1000
    由于该算法需要32位运算,所以该公式的另一个变种很流行:
    Gray = (R30 + G59 + B*11 + 50) / 100

    整数移位算法
    上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。移位比除法快多了,所以可以将系数缩放成2的整数幂。

    习惯上使用16位精度,2的16次幂是65536,所以这样计算系数:
    0.299 65536 = 19595.264 ≈ 19595
    0.587
    65536 + (0.264) = 38469.632 + 0.264 = 38469.896 ≈ 38469
    0.114 * 65536 + (0.896) = 7471.104 + 0.896 = 7472

    2至20位精度的系数:
    Gray = (R1 + G2 + B1) >> 2
    Gray = (R
    2 + G5 + B1) >> 3
    Gray = (R4 + G10 + B2) >> 4
    Gray = (R
    9 + G19 + B4) >> 5
    Gray = (R19 + G37 + B8) >> 6
    Gray = (R
    38 + G75 + B15) >> 7
    Gray = (R76 + G150 + B30) >> 8
    Gray = (R
    153 + G300 + B59) >> 9
    Gray = (R306 + G601 + B117) >> 10
    Gray = (R
    612 + G1202 + B234) >> 11
    Gray = (R1224 + G2405 + B467) >> 12
    Gray = (R
    2449 + G4809 + B934) >> 13
    Gray = (R4898 + G9618 + B1868) >> 14
    Gray = (R
    9797 + G19235 + B3736) >> 15
    Gray = (R19595 + G38469 + B7472) >> 16
    Gray = (R
    39190 + G76939 + B14943) >> 17
    Gray = (R78381 + G153878 + B29885) >> 18
    Gray = (R
    156762 + G307757 + B59769) >> 19
    Gray = (R313524 + G615514 + B*119538) >> 20

    仔细观察上面的等式,这些精度实际上是一样的:3与4、7与8、10与11、13与14、19与20
    所以16位运算下最好的计算公式是使用7位精度,比先前那个系数缩放100倍的精度高,而且速度快:
    Gray = (R38 + G75 + B*15) >> 7

    其实最有意思的还是那个2位精度的,完全可以移位优化:
    Gray = (R + (WORD)G<<1 + B) >> 2

    3.红外视频到彩虹图的换算:
    内容转载自博客:http://blog.sina.com.cn/s/blog_8924265b0101ext1.html
    将灰度图像的灰度值分别转换为RBG三原色,生成伪彩色。
    彩虹图一般为
    // 红 255, 0, 0 255
    // 橙 255, 127, 0 204
    // 黄 255, 255, 0 153
    // 绿 0, 255, 0 102
    // 青 0, 255, 255 51
    // 蓝 0, 0, 255 0
    六种颜色。需要把0-255分成6段,每段51
    转换成彩虹图之后,运用camshift进行跟踪即可。
    4.具体实现:在opencv的camshift例程中,找到主函数中的frame.copyTo(image)一句,在这之后加入以下代码:

    1. Mat test(image.rows, image.cols, CV_8UC3);//RGB图像
    2. Mat test_grey;
    3. cvtColor(image, test_grey, COLOR_BGR2GRAY);
    4. int tmp = 0;
    5. Mat img;
    6. cvtColor(image, img, COLOR_BGR2GRAY);
    7. Mat img_color(image.rows, image.cols, CV_8UC3);//构造RGB图像
    8. #define IMG_B(img,y,x)img.at<Vec3b>(y,x)[0]
    9. #define IMG_G(img,y,x)img.at<Vec3b>(y,x)[1]
    10. #define IMG_R(img,y,x)img.at<Vec3b>(y,x)[2]
    11. uchar tmp2 = 0;
    12. for (int y = 0; y<img.rows; y++)//转为彩虹图的具体算法,主要思路是把灰度图对应的0~255的数值分别转换成彩虹色:红、橙、黄、绿、青、蓝。
    13. {
    14. for (int x = 0; x<img.cols; x++)
    15. {
    16. tmp2 = img.at<uchar>(y, x);
    17. if (tmp2 <= 51)
    18. {
    19. IMG_B(img_color, y, x) = 255;
    20. IMG_G(img_color, y, x) = tmp2 * 5;
    21. IMG_R(img_color, y, x) = 0;
    22. }
    23. else if(tmp2 <= 102)
    24. {
    25. tmp2 -= 51;
    26. IMG_B(img_color, y, x) = 255 - tmp2 * 5;
    27. IMG_G(img_color, y, x) = 255;
    28. IMG_R(img_color, y, x) = 0;
    29. }
    30. else if(tmp2 <= 153)
    31. {
    32. tmp2 -= 102;
    33. IMG_B(img_color, y, x) = 0;
    34. IMG_G(img_color, y, x) = 255;
    35. IMG_R(img_color, y, x) = tmp2 * 5;
    36. }
    37. else if(tmp2 <= 204)
    38. {
    39. tmp2 -= 153;
    40. IMG_B(img_color, y, x) = 0;
    41. IMG_G(img_color, y, x) = 255 - uchar(128.0*tmp2 / 51.0 + 0.5);
    42. IMG_R(img_color, y, x) = 255;
    43. }
    44. else
    45. {
    46. tmp2 -= 204;
    47. IMG_B(img_color, y, x) = 0;
    48. IMG_G(img_color, y, x) = 127 - uchar(127.0*tmp2 / 51.0 + 0.5);
    49. IMG_R(img_color, y, x) = 255;
    50. }
    51. }
    52. }
    53. imshow("CamShift", image);
    54. image = img_color;