CIAreaHistogram gives me all 0 except the last element?

I want to calculate the NSImage histogram, so I turned to CIFilter naturally. There a filter called CIAreaHistogram does what I want. Here is my code:

 NSBitmapImageRep *rep = [image bitmapImageRepresentation]; CIImage* hImage = nil; @autoreleasepool { CIImage *input = [[CIImage alloc] initWithBitmapImageRep:rep]; CIFilter *histogramFilter = [CIFilter filterWithName:@"CIAreaHistogram"]; [histogramFilter setDefaults]; [histogramFilter setValue:input forKey:kCIInputImageKey]; [histogramFilter setValue:[CIVector vectorWithCGRect:[input extent]] forKeyPath:@"inputExtent"]; [histogramFilter setValue:[NSNumber numberWithInt:256] forKeyPath:@"inputCount"]; [histogramFilter setValue:[NSNumber numberWithFloat:1.0] forKey:@"inputScale"]; hImage = [histogramFilter valueForKey:kCIOutputImageKey]; input = nil; NSImage *result = nil; @autoreleasepool { NSCIImageRep *rep = [NSCIImageRep imageRepWithCIImage:hImage]; result = [[NSImage alloc] initWithSize:rep.size]; [result addRepresentation:rep]; } NSBitmapImageRep *imgRep = [result bitmapImageRepresentation]; for (int y = 0; y < imgRep.size.height; y ++) { for (int x = 0; x < imgRep.size.width; x ++) { NSUInteger pixel[4]; [imgRep getPixel:pixel atX:xy:y]; NSLog(@"(%d, %d): %lu - %lu - %lu - %lu", x, y, pixel[0], pixel[1], pixel[2], pixel[3]); } } } 

bitmapImageRepresentation is just a help method that converts NSImage to NSBitmapImageRep . I tested and used a lot with it, it seems like it's cool.

And the output will be listed below:

 (0, 0): 0 - 0 - 0 - 0 (1, 0): 0 - 0 - 0 - 0 (2, 0): 0 - 0 - 0 - 0 (3, 0): 0 - 0 - 0 - 0 (4, 0): 0 - 0 - 0 - 0 (5, 0): 0 - 0 - 0 - 0 (6, 0): 0 - 0 - 0 - 0 (7, 0): 0 - 0 - 0 - 0 (8, 0): 0 - 0 - 0 - 0 (9, 0): 0 - 0 - 0 - 0 (10, 0): 0 - 0 - 0 - 0 (11, 0): 0 - 0 - 0 - 0 (12, 0): 0 - 0 - 0 - 0 (13, 0): 0 - 0 - 0 - 0 (14, 0): 0 - 0 - 0 - 0 (15, 0): 0 - 0 - 0 - 0 (16, 0): 0 - 0 - 0 - 0 (17, 0): 0 - 0 - 0 - 0 (18, 0): 0 - 0 - 0 - 0 (19, 0): 0 - 0 - 0 - 0 (20, 0): 0 - 0 - 0 - 0 (21, 0): 0 - 0 - 0 - 0 (22, 0): 0 - 0 - 0 - 0 (23, 0): 0 - 0 - 0 - 0 (24, 0): 0 - 0 - 0 - 0 (25, 0): 0 - 0 - 0 - 0 (26, 0): 0 - 0 - 0 - 0 (27, 0): 0 - 0 - 0 - 0 (28, 0): 0 - 0 - 0 - 0 (29, 0): 0 - 0 - 0 - 0 (30, 0): 0 - 0 - 0 - 0 (31, 0): 0 - 0 - 0 - 0 (32, 0): 0 - 0 - 0 - 0 (33, 0): 0 - 0 - 0 - 0 (34, 0): 0 - 0 - 0 - 0 (35, 0): 0 - 0 - 0 - 0 (36, 0): 0 - 0 - 0 - 0 (37, 0): 0 - 0 - 0 - 0 (38, 0): 0 - 0 - 0 - 0 (39, 0): 0 - 0 - 0 - 0 (40, 0): 0 - 0 - 0 - 0 (41, 0): 0 - 0 - 0 - 0 (42, 0): 0 - 0 - 0 - 0 (43, 0): 0 - 0 - 0 - 0 (44, 0): 0 - 0 - 0 - 0 (45, 0): 0 - 0 - 0 - 0 (46, 0): 0 - 0 - 0 - 0 (47, 0): 0 - 0 - 0 - 0 (48, 0): 0 - 0 - 0 - 0 (49, 0): 0 - 0 - 0 - 0 (50, 0): 0 - 0 - 0 - 0 (51, 0): 0 - 0 - 0 - 0 (52, 0): 0 - 0 - 0 - 0 (53, 0): 0 - 0 - 0 - 0 (54, 0): 0 - 0 - 0 - 0 (55, 0): 0 - 0 - 0 - 0 (56, 0): 0 - 0 - 0 - 0 (57, 0): 0 - 0 - 0 - 0 (58, 0): 0 - 0 - 0 - 0 (59, 0): 0 - 0 - 0 - 0 (60, 0): 0 - 0 - 0 - 0 (61, 0): 0 - 0 - 0 - 0 (62, 0): 0 - 0 - 0 - 0 (63, 0): 0 - 0 - 0 - 0 (64, 0): 0 - 0 - 0 - 0 (65, 0): 0 - 0 - 0 - 0 (66, 0): 0 - 0 - 0 - 0 (67, 0): 0 - 0 - 0 - 0 (68, 0): 0 - 0 - 0 - 0 (69, 0): 0 - 0 - 0 - 0 (70, 0): 0 - 0 - 0 - 0 (71, 0): 0 - 0 - 0 - 0 (72, 0): 0 - 0 - 0 - 0 (73, 0): 0 - 0 - 0 - 0 (74, 0): 0 - 0 - 0 - 0 (75, 0): 0 - 0 - 0 - 0 (76, 0): 0 - 0 - 0 - 0 (77, 0): 0 - 0 - 0 - 0 (78, 0): 0 - 0 - 0 - 0 (79, 0): 0 - 0 - 0 - 0 (80, 0): 0 - 0 - 0 - 0 (81, 0): 0 - 0 - 0 - 0 (82, 0): 0 - 0 - 0 - 0 (83, 0): 0 - 0 - 0 - 0 (84, 0): 0 - 0 - 0 - 0 (85, 0): 0 - 0 - 0 - 0 (86, 0): 0 - 0 - 0 - 0 (87, 0): 0 - 0 - 0 - 0 (88, 0): 0 - 0 - 0 - 0 (89, 0): 0 - 0 - 0 - 0 (90, 0): 0 - 0 - 0 - 0 (91, 0): 0 - 0 - 0 - 0 (92, 0): 0 - 0 - 0 - 0 (93, 0): 0 - 0 - 0 - 0 (94, 0): 0 - 0 - 0 - 0 (95, 0): 0 - 0 - 0 - 0 (96, 0): 0 - 0 - 0 - 0 (97, 0): 0 - 0 - 0 - 0 (98, 0): 0 - 0 - 0 - 0 (99, 0): 0 - 0 - 0 - 0 (100, 0): 0 - 0 - 0 - 0 (101, 0): 0 - 0 - 0 - 0 (102, 0): 0 - 0 - 0 - 0 (103, 0): 0 - 0 - 0 - 0 (104, 0): 0 - 0 - 0 - 0 (105, 0): 0 - 0 - 0 - 0 (106, 0): 0 - 0 - 0 - 0 (107, 0): 0 - 0 - 0 - 0 (108, 0): 0 - 0 - 0 - 0 (109, 0): 0 - 0 - 0 - 0 (110, 0): 0 - 0 - 0 - 0 (111, 0): 0 - 0 - 0 - 0 (112, 0): 0 - 0 - 0 - 0 (113, 0): 0 - 0 - 0 - 0 (114, 0): 0 - 0 - 0 - 0 (115, 0): 0 - 0 - 0 - 0 (116, 0): 0 - 0 - 0 - 0 (117, 0): 0 - 0 - 0 - 0 (118, 0): 0 - 0 - 0 - 0 (119, 0): 0 - 0 - 0 - 0 (120, 0): 0 - 0 - 0 - 0 (121, 0): 0 - 0 - 0 - 0 (122, 0): 0 - 0 - 0 - 0 (123, 0): 0 - 0 - 0 - 0 (124, 0): 0 - 0 - 0 - 0 (125, 0): 0 - 0 - 0 - 0 (126, 0): 0 - 0 - 0 - 0 (127, 0): 0 - 0 - 0 - 0 (128, 0): 0 - 0 - 0 - 0 (129, 0): 0 - 0 - 0 - 0 (130, 0): 0 - 0 - 0 - 0 (131, 0): 0 - 0 - 0 - 0 (132, 0): 0 - 0 - 0 - 0 (133, 0): 0 - 0 - 0 - 0 (134, 0): 0 - 0 - 0 - 0 (135, 0): 0 - 0 - 0 - 0 (136, 0): 0 - 0 - 0 - 0 (137, 0): 0 - 0 - 0 - 0 (138, 0): 0 - 0 - 0 - 0 (139, 0): 0 - 0 - 0 - 0 (140, 0): 0 - 0 - 0 - 0 (141, 0): 0 - 0 - 0 - 0 (142, 0): 0 - 0 - 0 - 0 (143, 0): 0 - 0 - 0 - 0 (144, 0): 0 - 0 - 0 - 0 (145, 0): 0 - 0 - 0 - 0 (146, 0): 0 - 0 - 0 - 0 (147, 0): 0 - 0 - 0 - 0 (148, 0): 0 - 0 - 0 - 0 (149, 0): 0 - 0 - 0 - 0 (150, 0): 0 - 0 - 0 - 0 (151, 0): 0 - 0 - 0 - 0 (152, 0): 0 - 0 - 0 - 0 (153, 0): 0 - 0 - 0 - 0 (154, 0): 0 - 0 - 0 - 0 (155, 0): 0 - 0 - 0 - 0 (156, 0): 0 - 0 - 0 - 0 (157, 0): 0 - 0 - 0 - 0 (158, 0): 0 - 0 - 0 - 0 (159, 0): 0 - 0 - 0 - 0 (160, 0): 0 - 0 - 0 - 0 (161, 0): 0 - 0 - 0 - 0 (162, 0): 0 - 0 - 0 - 0 (163, 0): 0 - 0 - 0 - 0 (164, 0): 0 - 0 - 0 - 0 (165, 0): 0 - 0 - 0 - 0 (166, 0): 0 - 0 - 0 - 0 (167, 0): 0 - 0 - 0 - 0 (168, 0): 0 - 0 - 0 - 0 (169, 0): 0 - 0 - 0 - 0 (170, 0): 0 - 0 - 0 - 0 (171, 0): 0 - 0 - 0 - 0 (172, 0): 0 - 0 - 0 - 0 (173, 0): 0 - 0 - 0 - 0 (174, 0): 0 - 0 - 0 - 0 (175, 0): 0 - 0 - 0 - 0 (176, 0): 0 - 0 - 0 - 0 (177, 0): 0 - 0 - 0 - 0 (178, 0): 0 - 0 - 0 - 0 (179, 0): 0 - 0 - 0 - 0 (180, 0): 0 - 0 - 0 - 0 (181, 0): 0 - 0 - 0 - 0 (182, 0): 0 - 0 - 0 - 0 (183, 0): 0 - 0 - 0 - 0 (184, 0): 0 - 0 - 0 - 0 (185, 0): 0 - 0 - 0 - 0 (186, 0): 0 - 0 - 0 - 0 (187, 0): 0 - 0 - 0 - 0 (188, 0): 0 - 0 - 0 - 0 (189, 0): 0 - 0 - 0 - 0 (190, 0): 0 - 0 - 0 - 0 (191, 0): 0 - 0 - 0 - 0 (192, 0): 0 - 0 - 0 - 0 (193, 0): 0 - 0 - 0 - 0 (194, 0): 0 - 0 - 0 - 0 (195, 0): 0 - 0 - 0 - 0 (196, 0): 0 - 0 - 0 - 0 (197, 0): 0 - 0 - 0 - 0 (198, 0): 0 - 0 - 0 - 0 (199, 0): 0 - 0 - 0 - 0 (200, 0): 0 - 0 - 0 - 0 (201, 0): 0 - 0 - 0 - 0 (202, 0): 0 - 0 - 0 - 0 (203, 0): 0 - 0 - 0 - 0 (204, 0): 0 - 0 - 0 - 0 (205, 0): 0 - 0 - 0 - 0 (206, 0): 0 - 0 - 0 - 0 (207, 0): 0 - 0 - 0 - 0 (208, 0): 0 - 0 - 0 - 0 (209, 0): 0 - 0 - 0 - 0 (210, 0): 0 - 0 - 0 - 0 (211, 0): 0 - 0 - 0 - 0 (212, 0): 0 - 0 - 0 - 0 (213, 0): 0 - 0 - 0 - 0 (214, 0): 0 - 0 - 0 - 0 (215, 0): 0 - 0 - 0 - 0 (216, 0): 0 - 0 - 0 - 0 (217, 0): 0 - 0 - 0 - 0 (218, 0): 0 - 0 - 0 - 0 (219, 0): 0 - 0 - 0 - 0 (220, 0): 0 - 0 - 0 - 0 (221, 0): 0 - 0 - 0 - 0 (222, 0): 0 - 0 - 0 - 0 (223, 0): 0 - 0 - 0 - 0 (224, 0): 0 - 0 - 0 - 0 (225, 0): 0 - 0 - 0 - 0 (226, 0): 0 - 0 - 0 - 0 (227, 0): 0 - 0 - 0 - 0 (228, 0): 0 - 0 - 0 - 0 (229, 0): 0 - 0 - 0 - 0 (230, 0): 0 - 0 - 0 - 0 (231, 0): 0 - 0 - 0 - 0 (232, 0): 0 - 0 - 0 - 0 (233, 0): 0 - 0 - 0 - 0 (234, 0): 0 - 0 - 0 - 0 (235, 0): 0 - 0 - 0 - 0 (236, 0): 0 - 0 - 0 - 0 (237, 0): 0 - 0 - 0 - 0 (238, 0): 0 - 0 - 0 - 0 (239, 0): 0 - 0 - 0 - 0 (240, 0): 0 - 0 - 0 - 0 (241, 0): 0 - 0 - 0 - 0 (242, 0): 0 - 0 - 0 - 0 (243, 0): 0 - 0 - 0 - 0 (244, 0): 0 - 0 - 0 - 0 (245, 0): 0 - 0 - 0 - 0 (246, 0): 0 - 0 - 0 - 0 (247, 0): 0 - 0 - 0 - 0 (248, 0): 0 - 0 - 0 - 0 (249, 0): 0 - 0 - 0 - 0 (250, 0): 0 - 0 - 0 - 0 (251, 0): 0 - 0 - 0 - 0 (252, 0): 0 - 0 - 0 - 0 (253, 0): 0 - 0 - 0 - 0 (254, 0): 0 - 0 - 0 - 0 (255, 0): 0 - 0 - 0 - 255 

All buckets are 0, except for the last alpha value. And interestingly, has anyone ever used this filter and kindly explained to me ... Thanks so much!

+4
source share
3 answers

I wrote a post on how to do this here: http://shapeof.com/archives/2011/08/drawing_a_histogram_with_core_image.html

Not enough: you need to read the values ​​as a float, not ints, which means you need to connect the CGBitmapContext to blit to. Or, if you keep everything on CI ground, you will need another filter to read the data and print something with it.

+1
source

When using Core Image (which you should do in your case), the context format argument determines that gobbledegook returns code that allows it to process one pixel at a time.

After choosing the correct format, here is the code that I used to access the exit from the CIAreaHistogram:

  CIFilter* histogram = [CIFilter filterWithName:@"CIAreaHistogram"]; [histogram setValue:inputImage forKey:@"inputImage"]; [histogram setValue:[CIVector vectorWithX:0.0 Y:0.0 Z:self.inputImage.extent.size.width W:self.inputImage.extent.size.height] forKey:@"inputExtent"]; [histogram setValue:@256 forKey:@"inputCount"]; [histogram setValue:@1.0 forKey:@"inputScale"]; /*id histogramData = [histogram valueForKey:@"outputData"]; if (histogramData) NSLog(@"outputData: %@", histogramData);*/ @autoreleasepool { CIImage* histogramImage = [histogram valueForKey:@"outputImage"]; int rowBytes = 256 * 4; // ARGB has 4 components uint8_t byteBuffer[rowBytes]; // Buffer to render into EAGLContext *myEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; NSDictionary *options = @{ kCIContextWorkingColorSpace : [NSNull null] }; CIContext *ctx = [CIContext contextWithEAGLContext:myEAGLContext options:options]; //CIContext* ctx = [[CIContext alloc] init]; [ctx render:histogramImage toBitmap:byteBuffer rowBytes:rowBytes bounds:[histogramImage extent] format:kCIFormatRGBAf colorSpace:nil]; for (int i = 0; i < 256; i++) { const uint8_t* pixel = &byteBuffer[i*4]; printf("%u, %u, %u\n", pixel[0], pixel[1], pixel[2]); } } 
+1
source

You need to pass the pixel as a link.

 [imgRep getPixel:&pixel atX:xy:y]; 
0
source

Source: https://habr.com/ru/post/1208087/


All Articles