標籤:

opencv 一種不均勻光照的補償方法

如果一張圖片中,光照不均勻,使用全局閾值時,就無法達到想要的閾值化效果。因此,不均勻光照的補償演算法研究,具有一定的意義。

當然,不均勻光照的補償方法有很多,本文只是記錄其中一種,具體效果如何,實際價值如何,還有待驗證。希望看到此博文的讀者,對不均勻光照有深入研究的,可以一起交流。

其主要思路為:

1、求取源圖I的平均灰度,並記錄rows和cols;

2、按照一定大小,分為N*M個方塊,求出每塊的平均值,得到子塊的亮度矩陣D;

3、用矩陣D的每個元素減去源圖的平均灰度,得到子塊的亮度差值矩陣E;

4、用雙立方差值法,將矩陣E差值成與源圖一樣大小的亮度分布矩陣R;

5、得到矯正後的圖像result=I-R;

好了,下面是OpenCV實現的代碼部分。其中blockSize建議取值32,當然其他值也可以試下效果

[cpp] view plain copy

  1. voidunevenLightCompensate(Mat&image,intblockSize)
  2. {
  3. if(image.channels()==3)cvtColor(image,image,7);
  4. doubleaverage=mean(image)[0];
  5. introws_new=ceil(double(image.rows)/double(blockSize));
  6. intcols_new=ceil(double(image.cols)/double(blockSize));
  7. MatblockImage;
  8. blockImage=Mat::zeros(rows_new,cols_new,CV_32FC1);
  9. for(inti=0;i<rows_new;i++)
  10. {
  11. for(intj=0;j<cols_new;j++)
  12. {
  13. introwmin=i*blockSize;
  14. introwmax=(i+1)*blockSize;
  15. if(rowmax>image.rows)rowmax=image.rows;
  16. intcolmin=j*blockSize;
  17. intcolmax=(j+1)*blockSize;
  18. if(colmax>image.cols)colmax=image.cols;
  19. MatimageROI=image(Range(rowmin,rowmax),Range(colmin,colmax));
  20. doubletemaver=mean(imageROI)[0];
  21. blockImage.at<float>(i,j)=temaver;
  22. }
  23. }
  24. blockImage=blockImage-average;
  25. MatblockImage2;
  26. resize(blockImage,blockImage2,image.size(),(0,0),(0,0),INTER_CUBIC);
  27. Matimage2;
  28. image.convertTo(image2,CV_32FC1);
  29. Matdst=image2-blockImage2;
  30. dst.convertTo(image,CV_8UC1);
  31. }

效果圖展示如下:


推薦閱讀:

八字過硬化解方法
夏季正確防晒方法教學視頻 全集
有什麼熬夜刷題工作保持精神的方法?
五香咸雞蛋的腌制方法與營養價值
鍛煉胸肌最有效的方法,如何鍛煉胸肌最有效,怎樣鍛煉胸肌最有效

TAG:方法 |