在线时间1 小时
UID3096255
注册时间2015-12-15
NXP金币0
该用户从未签到
新手上路

- 积分
- 13
- 最后登录
- 2016-10-19
|
在飞思卡尔智能车比赛中,对于摄像头组,从摄像头模块中采集到的一副图像,除了硬件二值化,还有自我软件二值化。硬件二值化好处在于方便开发,但是在环境较恶劣的情况下,二值化后的图像可能不好接收。而像OV7620这样输出灰度图的摄像头,我们可以对其做自适应环境的二值化。在二值化中,OTSU,大津法,那可是相当不错,此处为大家奉上转载好帖介绍OTSU及其C语言实现。
OTSU算法是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法。 1. OTSU算法原理简介 对于一幅图像,设当前景与背景的分割阈值为t时,前景点占图像比例为w0,均值为u0,背景点占图像比例为w1,均值为u1。则整个图像的均值为u = w0*u0+w1*u1。建立目标函数g(t)=w0*(u0-u)^2+w1*(u1-u)^2,g(t)就是当分割阈值为t时的类间方差表达式。OTSU算法使得g(t)取得全局最大值,当g(t)为最大时所对应的t称为最佳阈值。OTSU算法又称为最大类间方差法。 2.OTSU算法例程下面是OSTU算法的C语言代码及其测试,代码基于opencv。- #include <cv.h>
- 2.#include <highgui.h>
- 3.
- 4.int otsu(IplImage *image)
- 5.{
- 6. assert(NULL != image);
- 7.
- 8. int width = image->width;
- 9. int height = image->height;
- 10. int x=0,y=0;
- 11. int pixelCount[256];
- 12. float pixelPro[256];
- 13. int i, j, pixelSum = width * height, threshold = 0;
- 14.
- 15. uchar* data = (uchar*)image->imageData;
- 16.
- 17. //初始化
- 18. for(i = 0; i < 256; i++)
- 19. {
- 20. pixelCount[i] = 0;
- 21. pixelPro[i] = 0;
- 22. }
- 23.
- 24. //统计灰度级中每个像素在整幅图像中的个数
- 25. for(i = y; i < height; i++)
- 26. {
- 27. for(j = x;j <width;j++)
- 28. {
- 29. pixelCount[data[i * image->widthStep + j]]++;
- 30. }
- 31. }
- 32.
- 33.
- 34. //计算每个像素在整幅图像中的比例
- 35. for(i = 0; i < 256; i++)
- 36. {
- 37. pixelPro[i] = (float)(pixelCount[i]) / (float)(pixelSum);
- 38. }
- 39.
- 40. //经典ostu算法,得到前景和背景的分割
- 41. //遍历灰度级[0,255],计算出方差最大的灰度值,为最佳阈值
- 42. float w0, w1, u0tmp, u1tmp, u0, u1, u,deltaTmp, deltaMax = 0;
- 43. for(i = 0; i < 256; i++)
- 44. {
- 45. w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
- 46.
- 47. for(j = 0; j < 256; j++)
- 48. {
- 49. if(j <= i) //背景部分
- 50. {
- 51. //以i为阈值分类,第一类总的概率
- 52. w0 += pixelPro[j];
- 53. u0tmp += j * pixelPro[j];
- 54. }
- 55. else //前景部分
- 56. {
- 57. //以i为阈值分类,第二类总的概率
- 58. w1 += pixelPro[j];
- 59. u1tmp += j * pixelPro[j];
- 60. }
- 61. }
- 62.
- 63. u0 = u0tmp / w0; //第一类的平均灰度
- 64. u1 = u1tmp / w1; //第二类的平均灰度
- 65. u = u0tmp + u1tmp; //整幅图像的平均灰度
- 66. //计算类间方差
- 67. deltaTmp = w0 * (u0 - u)*(u0 - u) + w1 * (u1 - u)*(u1 - u);
- 68. //找出最大类间方差以及对应的阈值
- 69. if(deltaTmp > deltaMax)
- 70. {
- 71. deltaMax = deltaTmp;
- 72. threshold = i;
- 73. }
- 74. }
- 75. //返回最佳阈值;
- 76. return threshold;
- 77.}
- 78.
- 79.int main(int argc, char* argv[])
- 80.{
- 81. IplImage* srcImage = cvLoadImage("D:\\technology\\CV\\Database\\image\\rice.png",0);
- 82. assert(NULL != srcImage);
- 83.
- 84. cvNamedWindow("src");
- 85. cvShowImage("src",srcImage);
- 86.
- 87. IplImage* biImage = cvCreateImage(cvGetSize(srcImage),8,1);
- 88.
- 89. //计算最佳阈值
- 90. int threshold = otsu(srcImage);
- 91. //对图像二值化
- 92. cvThreshold(srcImage,biImage,threshold,255,CV_THRESH_BINARY);
- 93.
- 94. cvNamedWindow("binary");
- 95. cvShowImage("binary",biImage);
- 96.
- 97. cvWaitKey(0);
- 98.
- 99. cvReleaseImage(&srcImage);
- 100. cvReleaseImage(&biImage);
- 101. cvDestroyWindow("src");
- 102. cvDestroyWindow("binary");
- 103.
- 104. return 0;
- 105.}
复制代码
下面是上述代码的运行结果图片。其中左边为原图像,右边为使用OTSU算法进行二值化后的图像。
|
评分
-
查看全部评分
|