日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

车道线识别之——增强黄色车道线

發布時間:2023/12/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 车道线识别之——增强黄色车道线 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為了更好的識別車道線,需要給黃色車道線增強,方法是將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")

總結

以上是生活随笔為你收集整理的车道线识别之——增强黄色车道线的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。