首页 文章

如何在CUDA上使用OpenCV查找图像的雾度范围? [关闭]

提问于
浏览
-1

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

  • 加载图片 .

  • 加载图像后,在要测试的单元格周围创建一个15x15的单元格

  • 找到测试单元的最大RGB并将其存储在一个数组中 .

  • 然后使用max RGB的值打印图像,据我所知,图像应该是暗图像 . RGB的最大值对应于图像的暗部分

这里的问题是我对图像处理的新手,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',y')表示颜色通道c(红色,绿色或蓝色通道之一)中像素位置(x',y')的强度,而omega(x,y)表示像素位置的邻域(x',y') .

因为我刚接触图像处理并打开cv,我不知道如何翻译这个等式

1 回答

  • 3

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

    主要步骤是:

    • 加载BGR图像

    • 使用最小值B,G,R( minValue3b )计算单个通道矩阵 .

    • 计算 patchSize x patchSize 邻域中的最小值( minFilter ) .

    NOTES

    • 您需要找到 minimum 值,而不是最大值 .

    • 为了避免在搜索邻域中的最小值时出现边界问题,您只需在图像周围添加足够大的边框,并使用最大允许值(即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;
    }
    

相关问题