Skip to content

Instantly share code, notes, and snippets.

@YHaruoka
Last active Apr 13, 2019
Embed
What would you like to do?
__global__ void convertToGray(uchar3 *color_pixel, unsigned char* gray_pixel) {
int ID = blockIdx.x*blockDim.x + threadIdx.x;
// カラーからグレースケール変換を実施
gray_pixel[ID] =
(unsigned char)(0.299f*color_pixel[ID].x
+ 0.587f*(float)color_pixel[ID].y
+ 0.114f*(float)color_pixel[ID].z);
}
#include <opencv2/opencv.hpp>
#include <iostream>
__global__ void convertToGray(uchar3 *color_pixel, unsigned char* gray_pixel);
int main(int argc, char *argv) {
// 画像をカラーで読み込む
cv::Mat input_img = cv::imread("test.jpg", 1);
if (input_img.empty() == true) {
std::cerr << "Error : cannot find input image" << std::endl;
}
// 画像のサイズを得る
int width = input_img.cols;
int height = input_img.rows;
std::cout << "Image_size : " << width << "×" << height << std::endl;
// ホスト(CPU)側配列(RGBを扱えるようunsigned char * 3で扱う)
uchar3* host_img_array_color = new uchar3[width * height];
unsigned char* host_img_array_gray = new unsigned char[width * height];
// 画素値を1次元配列化(OpenCVは画素がBGRの順なのでRGBの順に直して入れる)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
host_img_array_color[x + y * width]
= make_uchar3(input_img.at<cv::Vec3b>(y, x)[2], input_img.at<cv::Vec3b>(y, x)[1], input_img.at<cv::Vec3b>(y, x)[0]);
}
}
// デバイス(GPU)側のメモリ確保
uchar3* device_img_array_color;
unsigned char* device_img_array_gray;
int datasize_color = sizeof(uchar3) * width * height;
int datasize_gray = sizeof(unsigned char) * width * height;
cudaMalloc((void**)&device_img_array_color, datasize_color);
cudaMalloc((void**)&device_img_array_gray, datasize_gray);
// データ転送(CPU → GPU)
cudaMemcpy(device_img_array_color, host_img_array_color, datasize_color, cudaMemcpyHostToDevice);
// GPU側実行関数
convertToGray << <width * height, 1 >> > (device_img_array_color, device_img_array_gray);
// データ転送(GPU → CPU)
cudaMemcpy(host_img_array_gray, device_img_array_gray, datasize_gray, cudaMemcpyDeviceToHost);
// 結果画像の出力
cv::Mat1b output_img(height, width);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
output_img.at<unsigned char>(y, x) = host_img_array_gray[x + y * width];
}
}
cv::imwrite("test_gray.jpg", output_img);
// 解放
cudaFree(device_img_array_color);
cudaFree(device_img_array_gray);
delete host_img_array_color;
delete host_img_array_gray;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment