整理何凯明去雾算法代码优化

来源:互联网 发布:移动网络机顶盒价格表 编辑:程序博客网 时间:2024/05/01 23:58
持续记录中~~~这个函数求取三个通道中最小值,然后以最小值组成一幅灰度图-darkchannel,并返回大气强度Adouble darkChannel(const cv::Mat &src,cv::Mat &dst){    cv::Mat rawtemp;    rawtemp.create(src.size(),src.type());    for (int i = 0; i < height; i++) {         const uchar* imgP = src.ptr<uchar>(i);        uchar* dstP = rawImage.ptr<uchar>(i);         for (int j = 0; j < width; j++) {             int b=imgP[3*j];             int g=imgP[3*j+1];             int r=imgP[3*j+2];            dstP[j] = IMAGE_MIN(IMAGE_MIN(b,g),r);        }     }     //把图像分成patch,求patch框内的最小值,得到dark_channel image//range 0-255 center(i,j),every pixel (i,j) of rawtemp's value is Rect minvalue// dx is patchSize/2//rawtemp is the return of function of minChannel    cv::Mat rect_img;     for(int j=0;j<height;j++){         for(int i=0;i<width;i++){            cv::getRectSubPix(rawtemp,cv::Size(patchSize,patchSize),cv::Point(j,i),rect_img);            double min_value = 0;             cv::minMaxLoc(rect_img,&min_value,0,0,0); //using saturate_cast to set pixel value [0,255]             dst.at<uchar>(j,i)= cv::saturate_cast<uchar>(min_value);         }     }    //求大气强度A,并没有分开求各个通道的A,取了整体的A值double maxval;    int minAtomsLight = 220;//经验值     minMaxLoc(dst,NULL,&maxval);     double A = min(minAtomsLight, (int)maxval);return A;}/////////////////////////////////////////////////////////////////////////////当然如果你对opencv比较熟悉的话,可以看出,上面那段代码的后半部分,也就是图像patch块的那部分可以简单的用中值滤波来代替,也就是上面那段代码可以这样写 double darkChannel(const cv::Mat &src,cv::Mat &dst){      Mat rawtemp;      rawtemp.create(src.size(),CV_8UC1);      for(int i=0; i<src.rows; i++)     {               const uchar* imgP = src.ptr<uchar>(i);         uchar* dstP = rawImage.ptr<uchar>(i);        for(int j=0; j<src.cols; j++)        {                 int b=imgP[3*j];            int g=imgP[3*j+1];            int r=imgP[3*j+2];            dstP[j] = IMAGE_MIN(IMAGE_MIN(b,g),r);        }   }  // GaussianBlur(rgbmin, MDCP, Size(patch,patch),0);   //imshow("DCP",MDCP);   medianBlur(rawtemp, rawtemp, patchSize);//求大气强度A,并没有分开求各个通道的A,取了整体的A值   double maxval;   int minAtomsLight = 220;//经验值   minMaxLoc(dst,NULL,&maxval);   double A = min(minAtomsLight, (int)maxval);   return A;}



用查找表求粗透射率    cv::Mat image_trans;    image_trans.create(nHeight,nWidth,CV_8UC1);    cv::Mat look_up;        look_up.create(1,256,CV_8UC1);        uchar* look_up_ptr = look_up.data;    //reservation_factor =0.95      for (int k = 0;k < 256; k++)        {            int value = 255*(1- w * k / A);            look_up_ptr[k] = cv::saturate_cast<uchar>(value);        }        cv::LUT(rawtemp,look_up,transmission);

如果不考虑细介质透射率,直接用上面求出的粗透射率来求去雾图,则

//dehazing image//t 是得到的transmission//al是大气强度 Mat getDehaze(Mat source, Mat t, int A){ double tmin = 0.1;    double tmax;    Scalar tran;    Vec3b src;    Mat dehazed = Mat::zeros(source.rows, source.cols, CV_8UC3);      //    Mat lookup;//    look_up.create(1,256,CV_8UC1);//    uchar* look_up_ptr = look_up.data;    for(int i=0; i<source.rows; i++)    {        for(int j=0; j<source.cols; j++)        {            tran = t.at<uchar>(i,j);            src = source.at<Vec3b>(i,j);            tmax = (tran.val[0]/255) < tmin ? tmin : (tran.val[0]/255);            //(I-A)/t +A            for(int k=0; k<3; k++)            {                dehazed.at<Vec3b>(i,j)[k] = abs((src.val[k] - A) / tmax + al) > 255 ? 255 : abs((src.val[k] - A) / tmax + al);            }        }    }    return dehazed;}



   

0 0
原创粉丝点击