cuda and opencv:I only want the same as the original picture

243 views Asked by At

I just want to put the test.jpg into the texture memory, and then through the text2D () to show the picture, but the results are very strange. The "result" should be the same as "gray".Click there to get the pic:window:gray and window:result.The "gray" was reduced to the original quarter and arranged in a row.

This is code I'm using

 #include <cuda_runtime.h>   
 #include <highgui/highgui.hpp>  
 #include <imgproc/imgproc.hpp>  
 #include "device_launch_parameters.h"
 #include <iostream>

using namespace std;
using namespace cv;   

texture<float, 2, cudaReadModeElementType> texRef;  

__global__ void transformKernel(uchar* output, int width, int height)  
{  
    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;  
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;  
    float u = x / (float)width;  
    float v = y / (float)height;  

    output[(y * width + x)] = tex2D(texRef, x, y);
}  

int main()  
{  

    Mat image = imread("test.jpg", 0);
    int width=512;
    int height=512;
    resize(image, image, Size(width, height));  
    imshow("gray", image);  

    cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 0, 0, 0, cudaChannelFormatKindFloat);

    cudaArray* cuArray;  
    cudaMallocArray(&cuArray, &channelDesc, width, height);  
    cudaMemcpyToArray(cuArray, 0, 0, image.data, sizeof(uchar)*width*height, cudaMemcpyHostToDevice);  

    texRef.addressMode[0] = cudaAddressModeWrap; 
    texRef.addressMode[1] = cudaAddressModeWrap;  
    texRef.filterMode = cudaFilterModeLinear;   
    texRef.normalized = false;                        
    cudaBindTextureToArray(texRef, cuArray, channelDesc);  

    Mat imageOutput = Mat(Size(width, height), CV_8UC1);  
    uchar * output = imageOutput.data;  

    cudaMalloc((void**)&output, width * height * sizeof(float));  

    dim3 dimBlock(16, 16);  
    dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y - 1) / dimBlock.y);  

    transformKernel << <dimGrid, dimBlock >> > (output, width, height);  

    cudaMemcpy(imageOutput.data, output, height*width, cudaMemcpyDeviceToHost);  

    imshow("result", imageOutput);  
    waitKey();  

    cudaFreeArray(cuArray);  
    cudaFree(output);  
}  

Could anyone tell me why?

1

There are 1 answers

0
biaodiluer On
#include <cuda_runtime.h>   
#include <highgui/highgui.hpp>  
#include <imgproc/imgproc.hpp>  
#include "device_launch_parameters.h"
#include <iostream>


using namespace std;
using namespace cv;   

texture<uchar, 2, cudaReadModeElementType> texRef; 

__global__ void transformKernel(uchar* output, int width, int height)  
{  
    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;  
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;  
    float u = x / (float)width;  
    float v = y / (float)height;  

    output[(y * width + x)] = tex2D(texRef, x, y);
}  

int main()  
{  

    Mat image = imread("test.jpg", 0);
    int width=512;
    int height=512;
    resize(image, image, Size(width, height));  
    imshow("gray", image);  

    cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(8, 0, 0, 0, cudaChannelFormatKindUnsigned);

    cudaArray* cuArray;  
    cudaMallocArray(&cuArray, &channelDesc, width, height);  

    cudaMemcpyToArray(cuArray, 0, 0, image.data, sizeof(uchar)*width*height, cudaMemcpyHostToDevice);  
    texRef.addressMode[0] = cudaAddressModeWrap; 
    texRef.addressMode[1] = cudaAddressModeWrap;  
    texRef.addressMode[2] = cudaAddressModeWrap;  
    texRef.filterMode = cudaFilterModePoint;
    texRef.normalized = false;           

    cudaBindTextureToArray(texRef, cuArray, channelDesc);  

    Mat imageOutput = Mat(Size(width, height), CV_8UC1);  
    uchar * output = imageOutput.data;  

    cudaMalloc((void**)&output, width * height * sizeof(uchar));  

    dim3 dimBlock(16, 16);  
    dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y - 1) / dimBlock.y);  

    transformKernel << <dimGrid, dimBlock >> > (output, width, height);  

    cudaMemcpy(imageOutput.data, output, height*width* sizeof(uchar), cudaMemcpyDeviceToHost);  

    imshow("result", imageOutput);  
    waitKey();  

    cudaFreeArray(cuArray);  
    cudaFree(output);  

}  

just change the "float" to "uchar"