当前位置:   article > 正文

基于动态阈值的白平衡算法 照片校色_vecybr

vecybr

话不多说,原理见上一篇博客,结果耶很好,直接贴代码:


  1. /*这个是基于动态阈值的自动白平衡算法做的照片颜色校正的程序*/
  2. /*Automatic White Balance Method*/
  3. /*输入包含照片名字的txt文本,输出加前缀的较色后的照片*/
  4. /*时间:2015.8.24*/
  5. #include <opencv2/core/core.hpp>
  6. #include <opencv2/highgui/highgui.hpp>
  7. #include <opencv2/face.hpp>
  8. #include <opencv2/xphoto/white_balance.hpp>
  9. #include <opencv2/xphoto.hpp>
  10. #include <opencv2/imgproc/imgproc.hpp>
  11. #include <iostream>
  12. #include <vector>
  13. using namespace std;
  14. using namespace cv;
  15. double baidianave(Mat frame,int n)
  16. {
  17. int a[256];
  18. for (int i=0;i<256;i++)
  19. {
  20. a[i]=0;
  21. }
  22. double sum=0;
  23. double ave;
  24. for (int i=0;i<n;i++)
  25. {
  26. int d=frame.at<double>(0,i);
  27. a[d]++;
  28. }
  29. int n0=255;
  30. for (int k=255;k>0;k--)
  31. {
  32. sum+=a[k];
  33. if (sum>frame.rows*frame.cols/10)
  34. {
  35. break;
  36. }
  37. n0--;
  38. }
  39. sum=0;
  40. for (int i=n0;i<256;i++)
  41. {
  42. sum+=a[i]*i;
  43. }
  44. ave=sum/(frame.rows*frame.cols/10);
  45. return ave;
  46. }
  47. double baidianave(Mat frame)
  48. {
  49. int a[256];
  50. //cvZero(a);
  51. for (int i=0;i<256;i++)
  52. {
  53. a[i]=0;
  54. }
  55. double sum=0;
  56. double ave;
  57. for (int i=0;i<frame.rows;i++)
  58. {
  59. for (int j=0;j<frame.cols;j++)
  60. {
  61. int d=(int)frame.at<uchar>(i,j);
  62. a[d]++;
  63. }
  64. }
  65. int n0=255;
  66. for (int k=255;k>0;k--)
  67. {
  68. sum+=a[k];
  69. if (sum>frame.rows*frame.cols/10)
  70. {
  71. break;
  72. }
  73. n0--;
  74. }
  75. sum=0;
  76. for (int i=n0;i<256;i++)
  77. {
  78. sum+=a[i]*i;
  79. }
  80. ave=sum/(frame.rows*frame.cols/10);
  81. return ave;
  82. }
  83. int main(int argc, char* argv[])
  84. {
  85. if (2 != argc)
  86. {
  87. cout << "Please enter the image list!" <<endl;
  88. return -1;
  89. }
  90. vector<string> file_names;
  91. FILE *file_list = fopen(argv[1],"r");
  92. char buf[255];
  93. memset(&buf,0,sizeof(buf));
  94. while(fgets(buf,255,file_list))
  95. {
  96. if(buf[strlen(buf)-1] == '\n')
  97. buf[strlen(buf)-1] = '\0';
  98. file_names.push_back(string(buf));
  99. }
  100. fclose(file_list);
  101. int count = file_names.size();
  102. for(int i=0; i<count; i++)
  103. {
  104. string img_nm = file_names[i];
  105. string img_mask = "c2" + img_nm;
  106. int pos = img_nm.rfind('.');
  107. string img_fmt = img_nm.substr(pos+1);
  108. if("jpg" != img_fmt)
  109. {
  110. cout << "Unknown format: " << img_fmt << endl;
  111. continue;
  112. }
  113. Mat frame= imread(img_nm,1);
  114. // cout<<frame.rows<<" "<<frame.cols<<endl;
  115. // cvShowImage("处理前图像",frame);
  116. int heightyiban=frame.rows;
  117. int widthyiban=frame.cols;
  118. double Mb,Db;//图像分成四部分,每部分Cb的均值和均方差
  119. double Mr,Dr;//Cr的均值和均方差
  120. Mat imageYCrCb = Mat::zeros(frame.size(), CV_8UC3);
  121. Mat imageCb = Mat::zeros(frame.size(), CV_8UC1);
  122. Mat imageCr = Mat::zeros(frame.size(), CV_8UC1);
  123. Mat imageY = Mat::zeros(frame.size(), CV_8UC1);
  124. cvtColor(frame,imageYCrCb,CV_BGR2YCrCb);
  125. std::vector<cv::Mat>ybr(imageYCrCb.channels());
  126. split(imageYCrCb,ybr);
  127. Mat imageb=Mat::zeros(frame.size(), CV_8UC1);
  128. Mat imagec=Mat::zeros(frame.size(), CV_8UC1);
  129. ybr[1].copyTo(imageb);
  130. ybr[2].copyTo(imagec);
  131. Mat savg,sfangcha;//全局scalar 变量用来放平均值和方差
  132. meanStdDev(ybr[2],savg,sfangcha);
  133. Mb=savg.at<double>(0);
  134. Db=sfangcha.at<double>(0);//求出第一部分cb的均值和均方差
  135. meanStdDev(ybr[1],savg,sfangcha);
  136. Mr=savg.at<double>(0);
  137. // cout<<"Mr: "<<Mr[0]<<endl;
  138. Dr=sfangcha.at<double>(0);;//求出第一部分cr的均值和均方差
  139. // cout<<"Dr: "<<Dr[0]<<endl;
  140. double b,c;
  141. if (Mb<0)//计算mb+db*sign(mb)
  142. {
  143. b=Mb+Db*(-1);
  144. }
  145. else
  146. b=Mb+Db;
  147. if (Mr<0)//计算1.5*mr+dr*sign(mb);
  148. {
  149. c=1.5*Mr+Dr*(-1);
  150. }
  151. else
  152. c=1.5*Mr+Dr;
  153. double Ymax=baidianave(ybr[0]);
  154. //下面是对第一部分进行白点的选择
  155. Mat Bbaidian=Mat::zeros(1,6000000,CV_64FC1);
  156. Mat Gbaidian=Mat::zeros(1,6000000,CV_64FC1);
  157. Mat Rbaidian=Mat::zeros(1,6000000,CV_64FC1);
  158. //CvScalar s1;
  159. int n1=0;
  160. // cout<<"b[0]: "<<b[0]<<" c[0]: "<<c[0]<<endl;
  161. for (int i=0;i<heightyiban;i++)
  162. {
  163. for (int j=0;j<widthyiban;j++)
  164. {
  165. if (((ybr[2].at<uchar>(i,j)-b)<(1.5*Db))&&((ybr[1].at<uchar>(i,j)-c)<(1.5*Dr)))
  166. {
  167. double d1=frame.at<Vec3b>(i,j)[0];
  168. Bbaidian.at<double>(0,n1)=d1;
  169. double d2=frame.at<Vec3b>(i,j)[1];
  170. Gbaidian.at<double>(0,n1)=d2;
  171. double d3=frame.at<Vec3b>(i,j)[2];
  172. Rbaidian.at<double>(0,n1)=d3;
  173. n1++;
  174. }
  175. }
  176. }
  177. double Bave1=baidianave(Bbaidian,n1);
  178. double Gave1=baidianave(Gbaidian,n1);
  179. double Rave1=baidianave(Rbaidian,n1);
  180. // cout<<"Bave1: "<<Bave1<<" Gave1: "<<Gave1<<" Rave1: "<<Rave1<<" Ymax: "<<Ymax<<endl;
  181. double Bgain1=Ymax/(Bave1);
  182. double Ggain1=Ymax/(Gave1);
  183. double Rgain1=Ymax/(Rave1);
  184. // cout<<Bgain1<<" "<<Ggain1<<" "<<Rgain1<<endl;
  185. for (int i=0;i<heightyiban;i++)
  186. {
  187. for (int j=0;j<widthyiban;j++)
  188. {
  189. int tb=Bgain1*frame.at<Vec3b>(i,j)[0];
  190. int tg=Ggain1*frame.at<Vec3b>(i,j)[1];
  191. int tr=Rgain1*frame.at<Vec3b>(i,j)[2];
  192. if (tb>255)
  193. {
  194. tb=255;
  195. }
  196. if (tg>255)
  197. {
  198. tg=255;
  199. }
  200. if (tr>255)
  201. {
  202. tr=255;
  203. }
  204. frame.at<Vec3b>(i,j)[0]=tb;
  205. frame.at<Vec3b>(i,j)[1]=tg;
  206. frame.at<Vec3b>(i,j)[2]=tr;
  207. }
  208. }
  209. imwrite(img_mask.c_str(),frame);
  210. cout<<"Finish!"<<endl;
  211. }
  212. return 0;
  213. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/287432
推荐阅读
相关标签
  

闽ICP备14008679号