__device__ int isInsideLine(int startX, int startY, int endX, int endY, int lineWidth, int x, int y)
{
// Calculate squared length of line segment
float len2 = powf(endY - startY, 2) + powf(endX - startX, 2);
// Calculate dot product of vectors
float dot = (x - startX) * (endX - startX) + (y - startY) * (endY - startY);
// Check if point is beyond starting point or ending point of line segment
if (dot < 0 || dot > len2) {
return 0;
}
// Calculate distance between point and line
float dist = abs((endY - startY) * x - (endX - startX) * y + endX * startY - endY * startX) / sqrtf(len2);
// Check if distance is less than half the line width
return (dist < lineWidth / 2.0f);
}
这是一个用于判断点是否在直线上的函数。函数接受起点坐标(startX, startY)、终点坐标(endX, endY)、线宽(lineWidth)、以及要判断的点坐标(x, y)作为参数。函数返回一个整数值,如果点在直线上,则返回1,否则返回0。
函数的实现过程如下:
__global__ void drawLineKernel(cv::cuda::PtrStep<uchar> nv12Data, int nv12Pitch, int width, int height, TyPoint start, TyPoint end, int thickness, uchar Y, uchar U, uchar V)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
if (x < width && y < height)
{
int yIndex = y * nv12Pitch + x;
int uvIndex = (y / 2) * nv12Pitch + (x / 2) * 2;
int startYIdx = start.y * nv12Pitch + start.x;
int endYIdx = end.y * nv12Pitch + end.x;
if (isInsideLine(start.x, start.y, end.x, end.y, thickness, x, y))
{
nv12Data.data[yIndex] = Y;
nv12Data.data[(uvIndex + nv12Pitch * height)] = U;
nv12Data.data[(uvIndex + nv12Pitch * height + 1)] = V;
}
}
}
这是一个用于在CUDA中绘制直线的内核函数。函数接受一个NV12格式的图像数据(nv12Data)、图像数据的行字节数(nv12Pitch)、图像的宽度(width)和高度(height)、起点坐标(start)、终点坐标(end)、线宽(thickness)以及颜色(Y、U、V)作为参数。
函数的实现过程如下:
void RGBtoYUV(unsigned char R, unsigned char G, unsigned char B, int& Y, int& U, int& V) {
Y = 0.2126 * R + 0.7152 * G + 0.0722 * B;
U = -0.1146 * R - 0.3854 * G + 0.5000 * B + 128;
V = 0.5000 * R - 0.4542 * G - 0.0458 * B + 128;
}
void drawLine(cv::cuda::GpuMat& nv12Frame, TyPoint start, TyPoint end, int thickness, cv::Scalar color)
{
int Y = 0, U = 0, V = 0;
RGBtoYUV(color[2], color[1], color[0], Y, U, V);
const dim3 block(32, 16);
const dim3 grid(divUp(nv12Frame.cols, block.x), divUp(nv12Frame.rows, block.y));
drawLineKernel << <grid, block>> > (nv12Frame, nv12Frame.step, nv12Frame.cols, nv12Frame.rows/3*2, start, end, thickness, (uchar)Y, (uchar)U, (uchar)V);
cudaThreadSynchronize();
}