下面是在文档中找到的代码
int myEmboss(void *inData,
unsigned int inRowBytes,
void *outData,
unsigned int outRowBytes,
unsigned int height,
unsigned int width,
void *kernel,
unsigned int kernel_height,
unsigned int kernel_width,
int divisor ,
vImage_Flags flags ) {
uint_8 kernel = {-2, -2, 0, -2, 6, 0, 0, 0, 0}; // 1
vImage_Buffer src = { inData, height, width, inRowBytes }; // 2
vImage_Buffer dest = { outData, height, width, outRowBytes }; // 3
unsigned char bgColor[4] = { 0, 0, 0, 0 }; // 4
vImage_Error err; // 5
err = vImageConvolve_ARGB8888( &src, //const vImage_Buffer *src
&dest, //const vImage_Buffer *dest,
NULL,
0, //unsigned int srcOffsetToROI_X,
0, //unsigned int srcOffsetToROI_Y,
kernel, //const signed int *kernel,
kernel_height, //unsigned int
kernel_width, //unsigned int
divisor, //int
bgColor,
flags | kvImageBackgroundColorFill
//vImage_Flags flags
);
return err;
}问题是:内核变量似乎引用了三种不同的类型:
这是真正的密码吗?如何编译这个函数?
发布于 2013-09-20 23:16:56
你是对的,这个函数是相当混乱的。我建议使用提供反馈小部件让苹果知道。
我认为您应该从函数签名中删除kernel、kernel_width和kernel_height参数。这些似乎是应用调用方提供的内核的函数的保留,但是这个例子是关于应用内部定义的内核的。
修正了kernel局部变量的声明,使其成为uint8_t数组,如下所示:
uint8_t kernel[] = {-2, -2, 0, -2, 6, 0, 0, 0, 0}; // 1然后,在调用vImageConvolve_ARGB8888()时,将kernel_width和kernel_height替换为3。因为内核是硬编码的,所以尺寸也是一样的.
发布于 2013-09-15 18:27:19
这就是我用它来处理从AVAssetReader视频中读取的帧的方式。这是一个模糊,但您可以改变内核,以满足您的需要。“imageData”当然可以通过其他方法获得,例如从UIImage获得。
CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer];
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);
void *imageData = CVPixelBufferGetBaseAddress(imageBuffer);
int16_t kernel[9];
for(int i = 0; i < 9; i++) {
kernel[i] = 1;
}
kernel[4] = 2;
unsigned char *newData= (unsigned char*)malloc(4*currSize);
vImage_Buffer inBuff = { imageData, height, width, 4*width };
vImage_Buffer outBuff = { newData, height, width, 4*width };
vImage_Error err=vImageConvolve_ARGB8888 (&inBuff,&outBuff,NULL, 0,0,kernel,3,3,10,nil,kvImageEdgeExtend);
if (err != kvImageNoError) NSLog(@"convolve error %ld", err);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
//newData holds the processed image发布于 2013-09-20 21:10:14
核只是卷积中使用的核。在数学上,它是矩阵与你的形象,以实现模糊/锐化/浮雕或其他效果。您提供的这个函数只是一个薄包装,围绕着视觉卷积函数。要实际执行卷积,您可以遵循下面的代码。代码都是手工输入的,所以不一定100%正确,但是应该指出正确的方向。
要使用此函数,首先需要对图像具有像素访问权限。假设您有一个UIImage,您可以这样做:
//image is a UIImage
CGImageRef img = image.CGImage;
CGDataProviderRef dataProvider = CGImageGetDataProvider(img);
CFDataRef cfData = CGDataProviderCopyData(dataProvider);
void * dataPtr = (void*)CFDataGetBytePtr(cfData);接下来,构建将传递给函数的vImage_Buffer。
vImage_Buffer inBuffer, outBuffer;
inBuffer.data = dataPtr;
inBuffer.width = CGImageGetWidth(img);
inBuffer.height = CGImageGetHeight(img);
inBuffer.rowBytes = CGImageGetBytesPerRow(img);也分配outBuffer
outBuffer.data = malloc(inBuffer.height * inBuffer.rowBytes)
// Setup width, height, rowbytes equal to inBuffer here现在我们创建内核,在您的示例中是相同的内核,它是一个3x3矩阵,如果它们是浮点数(它们需要是int),则将值乘以一个除数。
int divisor = 1000;
CGSize kernalSize = CGSizeMake(3,3);
int16_t *kernel = (int16_t*)malloc(sizeof(int16_t) * 3 * 3);
// Assign kernel values to the emboss kernel
// uint_8 kernel = {-2, -2, 0, -2, 6, 0, 0, 0, 0} // * 1000 ;现在对图像执行卷积!
//Use a background of transparent black as temp
Pixel_8888 temp = 0;
vImageConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, kernel, kernelSize.width, kernelSize.height, divisor, temp, kvImageBackgroundColorFill);现在,用UIImage和您的完成构建一个新的outBuffer!
请记住释放内核和outBuffer数据。
https://stackoverflow.com/questions/18811662
复制相似问题