Ora*_*kan 5 cocoa objective-c core-image cifilter
我想计算a的直方图CGImage.我正在使用CIAreaHistogram内置CoreImage过滤器.
Justin Mrkva已经做了类似的事情.他说:
我得到直方图本身的CIImage,然后我通过自定义内核运行(参见结尾)将alpha值设置为1(因为否则直方图计算的alpha值被预乘)然后将其转换为NSBitmapImageRep.
我的问题是:是否有可能获得直方图数据而无需创建自定义内核?如果是这样,怎么样?
以下代码只是尝试渲染直方图而不修改alpha值:
- (void)printHistogram:(CGImageRef)img {
NSNumber* buckets = @10;
CIImage* img_ = [CIImage imageWithCGImage:img];
CIFilter* histF = [CIFilter filterWithName:@"CIAreaHistogram"];
[histF setValue:img_ forKey:@"inputImage"];
[histF setValue:[CIVector vectorWithX:0.0
Y:0.0
Z:CGImageGetWidth(img)
W:CGImageGetHeight(img)]
forKey:@"inputExtent"];
[histF setValue:buckets forKey:@"inputCount"];
[histF setValue:@1.0 forKey:@"inputScale"];
CIImage* histImg = [histF valueForKey:@"outputImage"];
int rowBytes = [buckets intValue] * 4; // ARGB has 4 components
uint8_t byteBuffer[rowBytes]; // Buffer to render into
CGColorSpaceRef cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CIContext* ctx = [[CIContext alloc] init];
[ctx render:histImg
toBitmap:byteBuffer
rowBytes:rowBytes
bounds:[histImg extent]
format:kCIFormatARGB8
colorSpace:cspace];
CGColorSpaceRelease(cspace);
for (int i=0; i<[buckets intValue]; i++) {
const uint8_t* pixel = &byteBuffer[i*4];
printf("%d:%u-%u-%u-%u\n",i,pixel[0],pixel[1],pixel[2],pixel[3]);
}
}
Run Code Online (Sandbox Code Playgroud)
给出输出(当在彩色照片上运行时):
0:0-0-0-0
1:0-0-0-0
2:0-0-0-0
3:0-0-0-0
4:0-0-0-0
5:0-0-0-0
6:0-0-0-0
7:0-0-0-0
8:0-0-0-0
9:255-33-6-7
Run Code Online (Sandbox Code Playgroud)
我尝试CIColorMatrix在渲染之前将alpha值设置为1.0:
CIFilter* biasF = [CIFilter filterWithName:@"CIColorMatrix"];
[biasF setDefaults];
[biasF setValue:histImg forKey:@"inputImage"];
[biasF setValue:[CIVector vectorWithX:0.0 Y:0.0 Z:0.0 W:1.0] forKey:@"inputBiasVector"];
Run Code Online (Sandbox Code Playgroud)
即使输出格式是ARGB,根据我从核心图像过滤器参考中所理解的,alpha分量是向量中的最后一个值(因此W:1.0).
但是这产生了以下输出:
0:255-255-255-255
1:255-255-255-255
2:255-255-255-255
3:255-255-255-255
4:255-255-255-255
5:255-255-255-255
6:255-255-255-255
7:255-255-255-255
8:255-255-0-255
9:255-66-11-15
Run Code Online (Sandbox Code Playgroud)
所有的帮助和建议将不胜感激!
编辑:我知道这个问题似乎相似.但是,接受的答案规定:
缺点是:您需要将值读取为浮点数,而不是整数,这意味着您必须将CGBitmapContext连接到blit.或者,如果您将所有内容保留在CI域中,您将需要另一个过滤器来读取数据并使用它打印出一些内容.
然而,看看Justin Mrkva的问题让我觉得应该可以获得整数值...如果我的想法有误,请告诉我.
再次感谢!
编辑2:所有的拳头,感谢David和jstn的评论.对不起,我花了很长时间才回到这里.我在一个项目上昼夜不停地工作(实际上是那个导致我遇到这个问题的项目,但我最终使用了一种完全不同的方法,不再使用CIAreaHistogram).现在我终于有了一些时间,我想回到这一点.即使我本身并不需要它,我仍然想要了解这个东西是如何工作的!
根据David Hayward的建议,我做了以下修改.
- (void)printHistogram:(CGImageRef)img {
NSNumber* buckets = @10;
CIImage* img_ = [CIImage imageWithCGImage:img];
CIFilter* histF = [CIFilter filterWithName:@"CIAreaHistogram"];
[histF setValue:img_ forKey:@"inputImage"];
[histF setValue:[CIVector vectorWithX:0.0
Y:0.0
Z:CGImageGetWidth(img)
W:CGImageGetHeight(img)]
forKey:@"inputExtent"];
[histF setValue:buckets forKey:@"inputCount"];
[histF setValue:@1.0 forKey:@"inputScale"];
CIImage* histImg = [histF valueForKey:@"outputImage"];
NSUInteger arraySize = [buckets intValue] * 4; // ARGB has 4 components
// CHANGE 1: Since I will be rendering in float values, I set up the
// buffer using CGFloat
CGFloat byteBuffer[arraySize]; // Buffer to render into
// CHANGE 2: I wasn't supposed to call [[CIContext alloc] init]
// this is a more proper way of getting the context
CIContext* ctx = [[NSGraphicsContext currentContext] CIContext];
// CHANGE 3: I use colorSpace:NULL to use the output cspace of the ctx
// CHANGE 4: Format is now kCIFormatRGBAf
[ctx render:histImg
toBitmap:byteBuffer
rowBytes:arraySize
bounds:[histImg extent]
format:kCIFormatRGBAf
colorSpace:NULL]; // uses the output cspace of the contetxt
// CHANGE 5: I print the float values
for (int i=0; i<[buckets intValue]; i++) {
const CGFloat* pixel = &byteBuffer[i*4];
printf("%d: %0.2f , %0.2f , %0.2f , %0.2f\n", i,pixel[0],pixel[1],pixel[2],pixel[3]);
}
}
Run Code Online (Sandbox Code Playgroud)
这给出了以下输出:
0: 0.00 , 0.00 , 0.00 , 0.00
1: 0.00 , 0.00 , 0.00 , 0.00
2: 0.00 , 0.00 , 0.00 , 0.00
3: 0.00 , 0.00 , 0.00 , 0.00
4: 0.00 , 0.00 , 0.00 , 0.00
5: 0.00 , 0.00 , 0.00 , 0.00
6: 0.00 , 0.00 , 1.00 , 0.00
7: 0.00 , 0.00 , 0.00 , 0.00
8: 0.00 , 0.00 , 0.00 , 0.00
9: 3.00 , 0.00 , 0.00 , 0.00
Run Code Online (Sandbox Code Playgroud)
使用各种格式以及如何解析信息会产生截然不同且荒谬的输出.
我很确定问题在于没有正确理解位图数据的表示方式.
还有什么建议?
三点建议:
| 归档时间: |
|
| 查看次数: |
2452 次 |
| 最近记录: |