为了更好的识别车道线,需要给黄色车道线增强,方法是将RGB图片转换为HSV图片,增强HSV图片的第三位(V)的数值,再转换成黑白图片。这个方法只适用于白天并且车道线清晰的场景。
如下是普通代码和CUDA代码

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <cuda.h>
#include <cuda_runtime.h>using namespace std;
using namespace cv;void RGB_to_HSV(const cv::Mat img_RGB, cv::Mat &img_HSV){int row = img_RGB.rows;int col = img_RGB.cols;int B, G, R;//Clearly what are they meanint V;    //V = max{R, G, B}int m;      //m = min{R, G, B}int S;    //S = (V - min{R, G, B}) / V, if V > min{R, G, B}//S = 0, if R = G = B//delta = max{R, G, B} - min{R, G, B}int H;      //H = 0, if max{R, G, B} = min{R, G, B}//H = (60 * (G - B)) / delta, if max{R, G, B} = R//H = 120 + (60 * (B - R)) / delta, if max{R, G, B} = G//H = 240 + (60 * (R - G)) / delta, if max{R, G, B} = Bfor (int i = 0; i < row; i = i + 1) {for (int j = 0; j < col; j = j + 1) {B = img_RGB.at<cv::Vec3b>(i, j)[0];G = img_RGB.at<cv::Vec3b>(i, j)[1];R = img_RGB.at<cv::Vec3b>(i, j)[2];//Confirm value V and mif ((B >= G) && (G >= R)) {V = B;m = R;} else if ((B >= G) && (G < R) && (B >= R)) {V = B;m = G;} else if ((B >= G) && (G < R) && (B < R)) {V = R;m = G;} else if ((B < G) && (G < R)) {V = R;m = B;} else if ((B < G) && (G >= R) && (B >= R)) {V = G;m = R;} else {V = G;m = B;}//Confirm value Sif (V > m) {S = (int)((V - m) / V);} else {S = 0;}//Confirm value Hif (V == m) {H = 0;} else if (V == R) {H = (int)(60 * (G - B) / (V - m));} else if (V == G) {H = (int)(120 + 60 * (B - R) / (V - m));} else {H = (int)(240 + 60 * (R - G) / (V - m));}//if H < 0, H should +360if (H < 0) {H = H + 360;}img_HSV.at<cv::Vec3b>(i, j)[0] = H;img_HSV.at<cv::Vec3b>(i, j)[1] = S;img_HSV.at<cv::Vec3b>(i, j)[2] = V;//cout << i << "  " << j << endl;   //testcode}}//end double for loop}//kernel code of void RGB_to_HSV(const cv::Mat img_RGB, cv::Mat&img_HSV)
__global__ void global_RGB_to_HSV(uchar3* d_image_RGB, uchar3* d_image_HSV ,int height, int width){int R, G, B;int V;    //V = max{R, G, B}int m;      //m = min{R, G, B}int S;    //S = (V - min{R, G, B}) / V, if V > min{R, G, B}//S = 0, if R = G = B//delta = max{R, G, B} - min{R, G, B}int H;      //H = 0, if max{R, G, B} = min{R, G, B}//H = (60 * (G - B)) / delta, if max{R, G, B} = R//H = 120 + (60 * (B - R)) / delta, if max{R, G, B} = G//H = 240 + (60 * (R - G)) / delta, if max{R, G, B} = Bfor (int row = blockDim.y * blockIdx.y + threadIdx.y; row < height; row = row + gridDim.y * blockDim.y) {for (int col = blockDim.x * blockIdx.x + threadIdx.x; col < width; col = col + gridDim.x * blockDim.x) {B = d_image_RGB[row * width + col].x;G = d_image_RGB[row * width + col].y;R = d_image_RGB[row * width + col].z;//Confirm value V and mif ((B >= G) && (G >= R)) {V = B;m = R;} else if ((B >= G) && (G < R) && (B >= R)) {V = B;m = G;} else if ((B >= G) && (G < R) && (B < R)) {V = R;m = G;} else if ((B < G) && (G < R)) {V = R;m = B;} else if ((B < G) && (G >= R) && (B >= R)) {V = G;m = R;} else {V = G;m = B;}//Confirm value Sif (V > m) {S = (int)((V - m) / V);} else {S = 0;}//Confirm value Hif (V == m) {H = 0;} else if (V == R) {H = (int)(60 * (G - B) / (V - m));} else if (V == G) {H = (int)(120 + 60 * (B - R) / (V - m));} else {H = (int)(240 + 60 * (R - G) / (V - m));}//if H < 0, H should +360if (H < 0) {H = H + 360;}d_image_HSV[row * width + col].x = H;d_image_HSV[row * width + col].y = S;d_image_HSV[row * width + col].z = V;}}
}//change(enhance) the V
void enhance_HSV(cv::Mat &image_hsv) {//int V;int row = image_hsv.rows;int col = image_hsv.cols;for (int i = 0; i < row; i = i + 1) {for (int j = 0; j < col; j = j + 1) {if (image_hsv.at<cv::Vec3b>(i, j)[2] >= 205) {image_hsv.at<cv::Vec3b>(i, j)[2] = 255;} else {image_hsv.at<cv::Vec3b>(i, j)[2] = 0;}}}
}//kernel code of void enhance_HSV(cv::Mat &image_hsv)
//CAUTION: __device__ 函数实际上是以__inline形式展开后直接编译到二进制代码中实现的,并不是真正的函数。
__device__ void device_enhance_HSV(uchar3* d_image_HSV, int height, int width) {for (int row = blockDim.y * blockIdx.y + threadIdx.y; row < height; row = row + gridDim.y * blockDim.y) {for (int col = blockDim.x * blockIdx.x + threadIdx.x; col < width; col = col + gridDim.x * blockDim.x) {if (d_image_HSV[row * width + col].z >= 205) {d_image_HSV[row * width + col].z = 255;} else {d_image_HSV[row * width + col].z = 0;}}}
}void HSV_to_gray(const cv::Mat image_hsv, cv::Mat &image_gray, cv::Mat &image_gray_) {int row = image_hsv.rows;int col = image_hsv.cols;for (int i = 0; i < row; i = i + 1) {for (int j = 0; j < col; j = j + 1) {if (image_hsv.at<cv::Vec3b>(i, j)[2] == 255) {image_gray.at<uchar>(i, j) = 255;} else {image_gray.at<uchar>(i, j) = 0;}}}for (int i = 1; i < row - 1; i = i + 1) {for (int j = 1; j < col - 1; j = j + 1) {if (image_gray.at<uchar>(i - 1, j - 1) +image_gray.at<uchar>(i - 1, j) +image_gray.at<uchar>(i - 1, j + 1) +image_gray.at<uchar>(i, j - 1) +image_gray.at<uchar>(i, j + 1) +image_gray.at<uchar>(i + 1, j - 1) +image_gray.at<uchar>(i + 1, j) +image_gray.at<uchar>(i + 1, j + 1) > 1000) {image_gray_.at<uchar>(i, j) = 255;} else {image_gray_.at<uchar>(i, j) = 0;}}}
}//kernel code of void HSV_to_gray(const cv::Mat image_hsv, cv::Mat &image_gray, cv::Mat &image_gray_)
__device__ void device_HSV_to_gray(const uchar3* d_image_HSV, uchar* d_image_gray, uchar* d_image_gray_, int height, int width) {for (int row = blockDim.y * blockIdx.y + threadIdx.y; row < height; row = row + gridDim.y * blockDim.y) {for (int col = blockDim.x * blockIdx.x + threadIdx.x; col < width; col = col + gridDim.x * blockDim.x) {if (d_image_HSV[row * width + col].z == 255) {d_image_gray[row * width + col] = 255;} else {d_image_gray[row * width + col] = 0;}}}__syncthreads();for (int row = blockDim.y * blockIdx.y + threadIdx.y; row < height; row = row + gridDim.y * blockDim.y) {for (int col = blockDim.x * blockIdx.x + threadIdx.x; col < width; col = col + gridDim.x * blockDim.x) {if (d_image_gray[(row - 1) * width + col - 1] +d_image_gray[(row - 1) * width + col] +d_image_gray[(row - 1) * width + col + 1] +d_image_gray[row * width + col - 1] +d_image_gray[row * width + col + 1] +d_image_gray[(row + 1) * width + col - 1] +d_image_gray[(row + 1) * width + col] +d_image_gray[(row + 1) * width + col + 1]  > 1000) {d_image_gray_[row * width + col] = 255;} else {d_image_gray_[row * width + col] = 0;}}}
}//Execute device functions, because device cannot be executed in main(), even cannot be configured(source: threads).
__global__ void global_do(uchar3* d_image_RGB, uchar3* d_image_HSV, uchar* d_image_gray, uchar* d_image_gray_, int height, int width) {//global_RGB_to_HSV(d_image_RGB, d_image_HSV, height, width);device_enhance_HSV(d_image_HSV, height, width);device_HSV_to_gray(d_image_HSV, d_image_gray, d_image_gray_, height, width);
}//a test of  __host__ __device__  together. Build SUCCEED!
//__host__ __device__ void foo(){//    printf("Hello world!\n");
//}int main()
{cv::Mat image_RGB = cv::imread("../../bgrtohsv/front.jpg");int height = image_RGB.rows;int width = image_RGB.cols;cv::Mat image_HSV(height, width, CV_8UC3);cv::Mat image_gray(height, width, CV_8UC1);cv::Mat image_gray_(height, width, CV_8UC1);size_t size_image_RGB = sizeof(uchar3) * height * width;size_t size_image_HSV = sizeof(uchar3) * height * width;size_t size_image_gray = sizeof(uchar) * height * width;size_t size_image_gray_ = sizeof(uchar) * height * width;uchar3* d_image_RGB = NULL;uchar3* d_image_HSV = NULL;uchar* d_image_gray = NULL;uchar* d_image_gray_ = NULL;cudaMalloc((void**)&d_image_RGB, size_image_RGB);cudaMalloc((void**)&d_image_HSV, size_image_HSV);cudaMalloc((void**)&d_image_gray, size_image_gray);cudaMalloc((void**)&d_image_gray_, size_image_gray_);cudaMemcpy(d_image_RGB, image_RGB.data, size_image_RGB, cudaMemcpyHostToDevice);cudaMemcpy(d_image_HSV, image_HSV.data, size_image_HSV, cudaMemcpyHostToDevice);cudaMemcpy(d_image_gray, image_gray.data, size_image_gray, cudaMemcpyHostToDevice);cudaMemcpy(d_image_gray_, image_gray_.data, size_image_gray_, cudaMemcpyHostToDevice);dim3 dimGrid(16, 16, 1);dim3 dimBlock(32, 32, 1);global_RGB_to_HSV<< <dimGrid, dimBlock>> >(d_image_RGB, d_image_HSV, height, width);cudaDeviceSynchronize();global_do<< <dimGrid, dimBlock>> >(d_image_RGB, d_image_HSV, d_image_gray, d_image_gray_, height, width);cudaDeviceSynchronize();    //wait for ALLcudaMemcpy(image_RGB.data, d_image_RGB, size_image_RGB, cudaMemcpyDeviceToHost);cudaMemcpy(image_HSV.data, d_image_HSV, size_image_HSV, cudaMemcpyDeviceToHost);cudaMemcpy(image_gray.data, d_image_gray, size_image_gray, cudaMemcpyDeviceToHost);cudaMemcpy(image_gray_.data, d_image_gray_, size_image_gray_, cudaMemcpyDeviceToHost);cudaDeviceSynchronize();//    RGB_to_HSV(image_RGB, image_HSV);
//    enhance_HSV(image_HSV);
//    HSV_to_gray(image_HSV, image_gray, image_gray_);cv::imshow("image_HSV", image_HSV);cv::imshow("image_gray", image_gray);cv::imshow("image_gray_", image_gray_);cv::waitKey(0);cv::imwrite("../../bgrtohsv/image_HSV.jpg", image_HSV);cv::imwrite("../../bgrtohsv/image_gray.jpg", image_gray);cv::imwrite("../../bgrtohsv/image_gray_.jpg", image_gray_);cudaFree(d_image_RGB);cudaFree(d_image_HSV);cudaFree(d_image_gray);cudaFree(d_image_gray_);//foo();return 0;
}

原图(image_RGB):image_HSV:image_gray:image_gray_:最后两张图是有差别的。

总结:
1.使用CUDA处理二维图像的万能公式:

for (int row = blockDim.y * blockIdx.y + threadIdx.y; row < height; row = row + gridDim.y * blockDim.y) {for (int col = blockDim.x * blockIdx.x + threadIdx.x; col < width; col = col + gridDim.x * blockDim.x) {do_something();}}

2.__device__定义的函数不能在main()函数里执行,甚至不能分配计算资源,需要放到__global__中执行,再在main()中执行。这条不对!!!

//Execute device functions, because device cannot be executed in main(), even cannot be configured(source: threads).
__global__ void global_abc(uchar3* d_image_HSV, uchar* d_image_gray, uchar* d_image_gray_, int height, int width) {device_enhance_HSV(d_image_HSV, height, width);device_HSV_to_gray(d_image_HSV, d_image_gray, d_image_gray_, height, width);
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)project(bgrtohsv)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)include_directories(include
${CUDA_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)link_directories(${OpenCV_LIBRARY_DIRS})find_package(CUDA REQUIRED)
find_package(OpenCV REQUIRED)#INCLUDE(/home/psdz/cmake-3.9.0/Modules/FindCUDA.cmake)FILE(GLOB SOURCES "*.cu" "*.cpp" "*.c" "*.h")set(CUDA_NVCC_FLAGS "-g -G")CUDA_ADD_EXECUTABLE(${PROJECT_NAME} main.cu)target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})#add_executable(${PROJECT_NAME} "main.cpp")

车道线识别之——增强黄色车道线相关推荐

  1. 基于视觉的车道线识别技术在智能车导航中的应用研究

    密级:公开 摘  要 摘  要 室外移动机器人的研究是机器人研究领域的重要分支,同时也是备受关注的热点领域.面向高速公路等结构化道路的室外移动机器人研究已成为现阶段民用交通运输领域移动机器人研究的主流 ...

  2. 车道线识别/Opencv/传统方法

    车道检测(Advanced Lane Finding Project) 实现步骤: 使用提供的一组棋盘格图片计算相机校正矩阵(camera calibration matrix)和失真系数(disto ...

  3. Simulink:车道线识别

    目录 1 博客内容 2 车道线识别过程 3 代码脚本 4 扩展应用 1 博客内容 近期看matlab(simulink)应用,关注到Github小伙伴分享的车道线识别用例,这里复盘供了解思路.作者:y ...

  4. 无人驾驶虚拟仿真(八)--图像处理之车道线识别3

    简介:在上一节中,我们完成了单张图片车道线的检测,在最终的结果中,可以比较明确的观察出车辆相对车道线的位置,接下来,我们要把这一功能移植到ROS系统中,将小车抓取到的图像都处理成车道线数据,并发布到下 ...

  5. 基于 Amazon DeepRacer Opensource 实现自定义车道线识别任务

    点击上方[凌云驭势 重塑未来] 一起共赴年度科技盛宴! 自动驾驶的视觉感知流程 在自动驾驶系统中,作为识别周边环境的"感官"角色,感知模块是整个系统安全.高效运行的基础,让汽车得以 ...

  6. 总奖金64万!含吸烟打电话检测、车道线识别等,2020中国华录杯·数据湖算法大赛火热进行中!...

    ●赛题背景● 以"数据驱动创新,赋能智慧城市"为主题的2020中国华录杯·数据湖算法大赛,围绕"华录数据湖+智慧城市"的核心理念,着力于智慧城市业务中的真实应用 ...

  7. 吸烟打电话检测、车道线识别等,2020中国华录杯·数据湖算法大赛火热进行中!...

    ●赛题背景● 随着互联网的高速发展,"万物数据化"浪潮奔腾而来.数据湖围绕数据的全生命周期管理打造新一代数字基础设施,在硬件层面构筑了高性能.低成本.智能化.高安全的数字经济底座, ...

  8. python视觉识别线条_简单车道线识别

    本文将介绍如何利用Opencv,对简单场景下的车道线进行离线识别.梳理整个识别过程的逻辑,并对过程中使用的相关知识点进行介绍.正文中使用C++实现,在文末也会附上利用python实现的代码,读者完全可 ...

  9. 车道线识别(一) 简单识别

    转载请注明出处 https://blog.csdn.net/gloria_iris/article/details/91625656 本博文是优达城Finding Lane Lines项目的总结,主要 ...

最新文章

  1. stm32cubemx生成不了keil工程文件_STM32CubeMX系列教程03_创建并生成代码工程
  2. 【编译原理】CFG分析树
  3. 数据结构-第九章 内部排序-知识点总结2
  4. oracle云数据库 免费的吗,使用免费的Oracle云服务-创建ATP数据库
  5. SAP License:MM自动过账科目特殊库存杂谈
  6. 样式定义Android界面样式
  7. [转]Java集合类: Set、List、Map、Queue使用场景梳理
  8. 89C52定时/计数器
  9. ASP.NET MVC显示UserControl控件(扩展篇)
  10. 2021爱分析・区域性银行数字化厂商全景报告
  11. C语言练习①一英寸是多少厘米?
  12. C语言:error C2084 函数“”已有主体
  13. 60秒轻松计算出任意一年任意一天星期几?
  14. run npm fund for details
  15. ESP-IDF的下载,设置,编译,烧录和监控
  16. 智能个性化推荐系统设计
  17. verilog基础---uart协议解析
  18. 三十天学会绘画pdf_【推荐】三十天学会绘画pdf|30天学会绘画pdf下载!
  19. python 制作 艾宾浩斯记忆表
  20. 什么是Cookie?Cookie有什么作用?

热门文章

  1. 查询用户上次登录时间问题
  2. 知识点六:jQuery遍历-同胞Siblings(), next(), nextAll()
  3. springMVC实现jsonp的跨域请求
  4. 【Python】第1次作业:圆面积的计算A,计算矩形面积,说句心里话A
  5. Leetcode Day1---双指针法 || 27移除元素、977. 有序数组的平方、209. 长度最小的子数组
  6. 小白也可以看懂的Numpy实操演示教程
  7. BZOJ3510 首都
  8. 洛谷2336 BZOJ2754 SCOI2012 喵星球上的点名 SA 莫队 二分
  9. 机器学习 刀光剑影 之屠龙刀_腾讯大数据
  10. 压缩包文件设置了加密怎么解密