- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用 cuda 实现多个黑色 (0) 和白色 (255) 图像侵 eclipse ,我使用方形 (5x5) 结构元素。我实现的内核采用 < strong>unsigned char 数组缓冲区,其中存储 nImg 图像 200X200 像素。为了允许同时侵 eclipse 多个图像,我制作了一个具有 3D 结构的网格:
我已经尝试通过扩展 sample 来实现它.
问题是,如果我将一个线程 block 考虑的像素存储到 block 的线程之间共享的共享缓冲区; 为了允许快速内存访问,该算法无法正常工作。我尝试更改对我来说出错的 bindex,但我找不到解决方案。
有什么建议吗?
这是我的代码:
//strel size
#define STREL_W 5
#define STREL_H 5
// distance from the cente of strel to strel width or height
#define R (STREL_H/2)
//size of the 2D region that each block consider i.e all the neighborns that each thread in a block consider
#define BLOCK_W (STREL_W+(2*R))
#define BLOCK_H (STREL_H+(2*R))
__global__ void erode_multiple_img_SM(unsigned char * buffer_in,
unsigned char * buffer_out,
int w,
int h ){
//array stored in shared memory,that contain all pixel neighborns that each thread in a block consider
__shared__ unsigned char fast_acc_arr[BLOCK_W*BLOCK_H];
// map thread in a 3D structure
int col = blockIdx.x * STREL_W + threadIdx.x -R ;
int row = blockIdx.y * STREL_H + threadIdx.y -R ;
int plane = blockIdx.z * blockDim.z + threadIdx.z;
// check if a foreground px of strel is not contain in a region of the image with size of strel (if only one px is not contain the image is eroded)
bool is_contain = true;
// clamp to edge of image
col = max(0,col);
col = min(col,w-1);
row = max(0,row);
row = min(row,h-1);
//map each thread in one dim coord to map 3D structure(grid) with image buffer(1D)
unsigned int index = (plane * h * w) + (row * w) + col;
unsigned int bindex = threadIdx.y * blockDim.y + threadIdx.x;
//each thread copy its pixel of the block to shared memory (shared with thread of a block)
fast_acc_arr[bindex] = buffer_in[index];
__syncthreads();
//the strel must be contain in image, thread.x and thread.y are the coords of the center of the mask that correspond to strel in image, and it must be contain in image
if((threadIdx.x >= R) && (threadIdx.x < BLOCK_W-R) && (threadIdx.y >= R) && (threadIdx.y <BLOCK_H-R)){
for(int dy=-R; dy<=R; dy++){
if(is_contain == false)
break;
for (int dx = -R ; dx <= R; dx++) {
//if only one element in mask is different from the value of strel el --> the strel is not contain in the mask --> the center of the mask is eroded (and it's no necessary to consider the other el of the mask this is the motivation of the break)
if (fast_acc_arr[bindex + (dy * blockDim.x) + dx ] != 255 ){
buffer_out[index ] = 0;
is_contain = false;
break;
}
}
}
// if the strel is contain into the image the the center is not eroded
if(is_contain == true)
buffer_out[index] = 255;
}
}
这是我的内核设置:
dim3 block(5,5,1);
dim3 grid(200/(block.x),200/(block.y),nImg);
我的内核调用:
erode_multiple_img_SM<<<grid,block>>>(dimage_src,dimage_dst,200,200);
我的图像输入和输出:
没有共享内存的代码(低速):
__global__ void erode_multiple_img(unsigned char * buffer_in,
unsigned char * buffer_out,
int w,int h ){
int col = blockIdx.x * blockDim.x + threadIdx.x;
int row = blockIdx.y * blockDim.y + threadIdx.y;
int plane = blockIdx.z * blockDim.z +threadIdx.z;
bool is_contain = true;
col = max(0,col);
col = min(col,w-1);
row = max(0,row);
row = min(row,h-1);
for(int dy=-STREL_H/2; dy<=STREL_H/2; dy++){
if(is_contain == false)
break;
for (int dx = -STREL_W/2 ; dx <= STREL_W/2; dx++) {
if (buffer_in[(plane * h * w) +( row + dy) * w + (col + dx) ] !=255 ){
buffer_out[(plane * h * w) + row * w + col ] = 0;
is_contain = false;
break;
}
}
}
if(is_contain == true)
buffer_out[(plane * h * w) + row * w +col ] = 255;
}
更新的算法
我尝试遵循 samples做卷积。我改变了输入图像,现在有 512x512 大小,我写了那个算法:
#define STREL_SIZE 5
#define TILE_W 16
#define TILE_H 16
#define R (STREL_H/2)
#define BLOCK_W (TILE_W+(2*R))
#define BLOCK_H (TILE_H+(2*R))
__global__ void erode_multiple_img_SM_v2(unsigned char * buffer_in,
unsigned char * buffer_out,
int w,int h ){
// Data cache: threadIdx.x , threadIdx.y
__shared__ unsigned char data[TILE_W +STREL_SIZE ][TILE_W +STREL_SIZE ];
// global mem address of this thread
int col = blockIdx.x * blockDim.x + threadIdx.x;
int row = blockIdx.y * blockDim.y + threadIdx.y;
int plane = blockIdx.z * blockDim.z +threadIdx.z;
int gLoc = (plane*h/w)+ row*w +col;
bool is_contain = true;
// load cache (32x32 shared memory, 16x16 threads blocks)
// each threads loads four values from global memory into shared mem
int x, y; // image based coordinate
if((col<w)&&(row<h)) {
data[threadIdx.x][threadIdx.y]=buffer_in[gLoc];
if (threadIdx.y > (h-STREL_SIZE))
data[threadIdx.x][threadIdx.y + STREL_SIZE]=buffer_in[gLoc + STREL_SIZE];
if (threadIdx.x >(w-STREL_SIZE))
data[threadIdx.x + STREL_SIZE][threadIdx.y]=buffer_in[gLoc+STREL_SIZE];
if ((threadIdx.x >(w-STREL_SIZE)) && (threadIdx.y > (h-STREL_SIZE)))
data[threadIdx.x+STREL_SIZE][threadIdx.y+STREL_SIZE] = buffer_in[gLoc+2*STREL_SIZE];
//wait for all threads to finish read
__syncthreads();
//buffer_out[gLoc] = data[threadIdx.x][threadIdx.y];
unsigned char min_value = 255;
for(x=0;x<STREL_SIZE;x++){
for(y=0;y<STREL_SIZE;y++){
min_value = min( (data[threadIdx.x+x][threadIdx.y+y]) , min_value);
}
}
buffer_out[gLoc]= min_value;
}
我的内核设置现在是:
dim3 block(16,16);
dim3 grid(512/(block.x),512/(block.y),nImg);
似乎围裙的像素没有复制到输出缓冲区
最佳答案
您可能需要阅读以下链接以获得有关如何实现图像卷积 CUDA 核函数的更详细的描述和更好的示例代码。
http://igm.univ-mlv.fr/~biri/Enseignement/MII2/Donnees/convolutionSeparable.pdf
https://www.evl.uic.edu/sjames/cs525/final.html
基本上使用大小为 (5 x 5) 的卷积滤波器并不意味着将线程 block 的大小设置为 (5 x 5)。
通常,对于不可分离的卷积,您可以使用大小为 (16 x 16) 的线程 block 来计算输出图像上的 (16 x 16) 像素 block 。为实现这一点,您需要协同使用 (16 x 16) 个线程,从输入图像读取一 block ((2+16+2) x (2+16+2)) 像素到共享内存。
关于c++ - cuda 多重图像侵 eclipse 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38072875/
我想腐 eclipse 具有特定结构元素的图像。 opencv 提供的默认元素形状为椭圆、矩形和十字形。 int erosion_type = MORPH_RECT; Mat element = ge
我正在处理以 30fps 的速度从相机获取图像的对象检测,这表明我对每一帧的处理速度应为 0.03 秒。由于我使用了腐 eclipse 功能,处理时间增加了,因此图像的处理延迟了几分之一秒,这不是实时
我有一个功能,可以根据区域大小或多或少地侵 eclipse 某些轮廓。然而,一旦它们被裁剪,它们就会丢失与原始图像相对应的正确坐标数据。 如何在保持其原始位置的同时将我的 eroded_contour
我对 Marvin 图像处理框架中的 Erosion 插件有疑问。我想做侵 eclipse ,但不幸的是,在那之后我在输出中没有图像。这是我的代码: tempPlugin = new Erosion
我有一个函数通过假设 anchor 是左上角或矩阵的第一个元素来执行膨胀/腐 eclipse 函数。 [1 1 1] [1 1 1] [1 1 1] 我有其他函数通过假设 anchor 是矩阵的中点来
我想平滑二值化图像的轮廓,认为腐 eclipse 是最好的方法。我知道正常的工作方式是使用 cvDilate(src, dst, 0, iter);其中 0 是 3x3 矩阵。 问题是 3x3 矩阵在
下面是在 Chrome 22.0.1229.79 Mac 上呈现的 SVG 图像的屏幕截图。原始的 svg 位于 jsfiddle 上: http://jsfiddle.net/LGBk5/ 左图是使
我需要检测文档上的文本 block 并取回它们的边界框,我听说我应该腐 eclipse 图像,这会将文本“弄脏”在一起并形成 Blob ,然后我可以使用 Blob 检测来找到文本是。目前我已经将图像二
我在 Windows 上的 Firefox 和 Chrome 中遇到了非系统字体的问题。这种字体是 Corbel。在 windows 上使用 Safari 和 Explorer 是可以的,在 Mac
我是一名优秀的程序员,十分优秀!