如何在CUDA上使用OpenCV查找图像的雾霾范围?

时间:2015-10-21 06:48:02

标签: c++ opencv image-processing cuda gpgpu

我试图找到图像的RGB值的最大值和最小值。 我打算去的流程是:

  1. 加载图片。
  2. 加载图像后,在要测试的单元格周围创建一个15x15的单元格
  3. 找到测试单元格的最大RGB并将其存储在一个数组中。
  4. 然后使用max RGB的值打印图像,据我所知,图像应该是暗图像。 RGB的最大值对应于图像的暗部分
  5. 这里的问题是我对图像处理的新手,opencv。 我不知道如何实现上面提到的这些事情i have attached a picture related to my doubt

    这是代码,我刚刚阅读了图像并获得了图像的一些细节

    #include "iostream"
    #include "string.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include "opencv2/opencv.hpp"
    
    float lambda=0.0001;    //lambda
    double _w=0.95;         //w
    int height=0;           //image Height
    int width=0;            //image Width
    int size=0;         //total number of pixels
    int blockdim = 32;
    
    char img_name[100]="1.png";
    
    Mat read_image()
    {
        Mat img = imread(img_name);
        height = img.rows;
        width = img.cols;
        size = img.rows*img.cols;
        Mat real_img(img.rows,img.cols,CV_32FC3);
        img.convertTo(real_img,CV_32FC3);
        return real_img;
     }
    
    //Main Function
    int main(int argc, char * argv[])
    {
         Mat img = read_image();
        /*****************************************************************/
        // Till here i have done my code. i.e. Read my image and get all   details about the image 
        // Now i'm not getting the logic to find the Min/Max of RGB values in an image for 
        // 15x15 cell
    
        return 0;
    }
    

    最后我想在GPU上实现这一点,我已经学到了很多关于GPU,CUDA和在GPU上运行的东西。现在我想做一些与GPU(CUDA)上的图像处理相关的东西

    我想计算每个块的图像雾度范围。这是通过找到用于反映雾度范围的暗通道值来完成的。这个概念来自Kaiming He的论文Single Image Haze Removal using Dark Channel Prior

    每个块的暗通道值定义如下:

    其中I ^ c(x&#39;,y&#39;)表示颜色通道c(红色,绿色或蓝色之一)中像素位置(x&#39;,y&#39;)的强度通道)和omega(x,y)表示像素位置的邻域(x&#39;,y&#39;)。

    因为我是图像处理和打开简历的新手,我不知道如何翻译这个等式

1 个答案:

答案 0 :(得分:3)

我前段时间已经实现了这个,下面是代码片段。可能可以进一步优化,你应该自己添加cuda支持,但这可能是一个很好的起点。

主要步骤是:

  1. 加载BGR图像
  2. 使用最小值B,G,R(minValue3b)计算单个通道矩阵。
  3. 计算patchSize x patchSize邻域(minFilter)中的最小值。
  4. 备注

    • 您需要找到最小值,而不是最大值。
    • 为了避免在搜索邻域中的最小值时出现边界问题,您只需在图像周围添加足够大的边框,并使用最大允许值(即255)。您可以使用copyMakeBorder

    输入:

    enter image description here

    DCP:

    enter image description here

    代码:

    #include <opencv2/opencv.hpp>
    using namespace cv;
    
    void minFilter(const Mat1b& src, Mat1b& dst, int radius)
    {
        Mat1b padded;
        copyMakeBorder(src, padded, radius, radius, radius, radius, BORDER_CONSTANT, Scalar(255));
    
        int rr = src.rows;
        int cc = src.cols;
        dst = Mat1b(rr, cc, uchar(0));
    
        for (int c = 0; c < cc; ++c)
        {
            for (int r = 0; r < rr; ++r)
            {
                uchar lowest = 255;
                for (int i = -radius; i <= radius; ++i)
                {
                    for (int j = -radius; j <= radius; ++j)
                    {
                        uchar val = padded(radius + r + i, radius + c + j);
                        if (val < lowest) lowest = val;
                    }
                }
                dst(r, c) = lowest;
            }
        }
    }
    
    
    void minValue3b(const Mat3b& src, Mat1b& dst)
    {
        int rr = src.rows;
        int cc = src.cols;
    
        dst = Mat1b(rr, cc, uchar(0));
    
        for (int c = 0; c<cc; ++c)
        {
            for (int r = 0; r<rr; ++r)
            {
                const Vec3b& v = src(r, c);
    
                uchar lowest = v[0];
                if (v[1] < lowest) lowest = v[1];
                if (v[2] < lowest) lowest = v[2];
                dst(r, c) = lowest;
            }
        }
    }
    
    void DarkChannel(const Mat3b& img, Mat1b& dark, int patchSize)
    {
        int radius = patchSize / 2;
    
        Mat1b low;
        minValue3b(img, low);
        minFilter(low, dark, radius);
    }
    
    
    int main()
    {
        // Load the image
        Mat3b img = imread("path_to_image");
    
        // Compute DCP
        Mat1b dark;
        DarkChannel(img, dark, 15);
    
        // Show results
        imshow("Img", img);
        imshow("Dark", dark);
        waitKey();
    
        return 0;
    }