How to get a meaningful CIAreaHistogram result?

I want to calculate a histogram of a CGImage . I use the built-in CoreImage filter.

Justin Mrkva did something similar to similar lines . He says:

I get CIImage for the histogram itself, which I then run through the custom kernel (see end of post) to set the alpha values โ€‹โ€‹to 1 (since otherwise the alpha value from the histogram calculations is pre-multiplied) and then converts it to NSBitmapImageRep .

My question is: can I get histogram data without creating my own kernel? If so, how?

The following code is simply trying to display a histogram without highlighting alpha values:

 - (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]); } } 

Providing output (when working in color photography):

 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 

I tried using CIColorMatrix to set alpha values โ€‹โ€‹to 1.0 before rendering:

 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"]; 

Although the output format is ARGB, from what I understand from the Core Image Filter link, the alpha component is the last value in the vector (thus W:1.0 ).

But this gave the following result:

 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 

All help and advice will be greatly appreciated!


EDIT: I know this question , it seems. However, the accepted answer provides:

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.

However, looking at Justin Mrkva's question, I think getting integer values โ€‹โ€‹should be possible ... Please let me know if there is a mistake in my thinking.

Thanks again!


EDIT 2: Fist of all, thanks to both David and jstn for their comments. Sorry, it took me so long to get back to this. I worked around the clock on the project (actually this project led me to this problem, but in the end I used a completely different approach that no longer uses the CIAreaHistogram). Now that I finally have time for my hands, I wanted to return to this. Although I do not need this, I still want to understand how this thing really works!

Following David Hayward's suggestions, I made the following changes.

 - (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]); } } 

This gives the following result:

 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 

A game with format variations and a method of analyzing information gives completely different and absurd outputs.

I am sure that the problem lies in the fact that you do not understand exactly how the raster data is presented.

Other offers?

+5
source share
6 answers

Three suggestions:

  • use inputScale to count the histogram. If inputScale is 1, then the resulting histogram bin value will be 1.0 (255 if ARGB8 is displayed) if the entire area has this bin value)
  • pass CI the working color space for rendering: toBitmap :. The Mavericks workspace is kCGColorSpaceGenericRGBLinear. On Yosemite, it's linear sRGB.
  • in OS X you can use kCIFormatRGBAf to get floating point data
  • on iOS, you can use kCIFormatRGBAh to receive data with a semi-stream.
+1
source

I struggled with this for a while, though on iOS. I wanted to get the histogram data from the live video for my own visualization, but I ran into the same problem as Justin Mrkva .

Even with the CIHistogramDisplayFilter output did not look completely right for me (too flat?), Plus the CIAreaHistogram consumed something like 25-30% of the CPU itself. This is before drawing to EAGLContext , not even returning data from the GPU yet ...

So, I completely abandoned Core Image and turned to vImage , which works fine. It still works intensively, but for me it is surprisingly smaller than the CIAreaHistogram , and the result matches what I see in Photoshop. This is not ideal if you are trying to stay completely on the GPU, but depending on your application, this might be the best choice (this is certainly more accurate).

This doesn't exactly answer your question, but here's how to get a histogram for CGImage using vImage. I am doing basically the same thing except CVPixelBuffer and blocking the base address. The order of the channels is different, but it does not matter:

 #import <Accelerate/Accelerate.h> CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image)); vImage_Buffer vImageBuffer; vImageBuffer.data = (UInt8 *)CFDataGetBytePtr(imageData); vImageBuffer.width = CGImageGetWidth(image); vImageBuffer.height = CGImageGetHeight(image); vImageBuffer.rowBytes = CGImageGetBytesPerRow(image); vImagePixelCount red[256]; vImagePixelCount green[256]; vImagePixelCount blue[256]; vImagePixelCount alpha[256]; vImagePixelCount *histogram[4] = { red, green, blue, alpha }; vImage_Error error = vImageHistogramCalculation_ARGB8888(&vImageBuffer, histogram, 0); if (error != kvImageNoError) NSLog(@"vImage error: %ld", error); CFRelease(imageData); // histogram now contains unsigned long counts for each channel 

I would still like to know how to use CIAreaHistogram in iOS correctly!

0
source

Here's how to do what you wanted to do initially; as it turned out, changing the format in context is what gives you all the different results you got.

This code example, by the way, uses an EAGLContext, which is supposedly faster, although in my experience this is not so far. However, here:

  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]); } } 
0
source

By the way, here is the working (and accurate) code for getting values โ€‹โ€‹from the CIAreaAverage Core Image filter:

 - (CIImage *)outputImage CGRect inputExtent = [self.inputImage extent]; CIVector *extent = [CIVector vectorWithX:inputExtent.origin.x Y:inputExtent.origin.y Z:inputExtent.size.width W:inputExtent.size.height]; CIImage* inputAverage = [CIFilter filterWithName:@"CIAreaAverage" keysAndValues:@"inputImage", self.inputImage, @"inputExtent", extent, nil].outputImage; //CIImage* inputAverage = [self.inputImage imageByApplyingFilter:@"CIAreaMinimum" withInputParameters:@{@"inputImage" : inputImage, @"inputExtent" : extent}]; EAGLContext *myEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; NSDictionary *options = @{ kCIContextWorkingColorSpace : [NSNull null] }; CIContext *myContext = [CIContext contextWithEAGLContext:myEAGLContext options:options]; size_t rowBytes = 32 ; // ARGB has 4 components uint8_t byteBuffer[rowBytes]; // Buffer to render into [myContext render:inputAverage toBitmap:byteBuffer rowBytes:rowBytes bounds:[inputAverage extent] format:kCIFormatRGBA8 colorSpace:nil]; const uint8_t* pixel = &byteBuffer[0]; float red = pixel[0] / 255.0; float green = pixel[1] / 255.0; float blue = pixel[2] / 255.0; NSLog(@"%f, %f, %f\n", red, green, blue); return outputImage; 

Output Example:

 2015-05-23 15:58:10.854 CIFunHouse[2400:489896] BSXPCMessage received error for message: Connection interrupted 2015-05-23 15:58:15.470 CIFunHouse[2400:489913] 0.000000, 0.000000, 0.305882 2015-05-23 15:58:15.582 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:15.622 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:15.665 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:15.706 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:15.748 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:15.792 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:15.834 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:15.874 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:15.915 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:15.956 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:15.998 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:16.040 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.079 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.121 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.163 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.205 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.247 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.288 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.330 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.372 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.413 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.455 CIFunHouse[2400:489895] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.496 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.543 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:16.579 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:16.623 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:16.667 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:16.705 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:16.746 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:16.788 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:16.829 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.873 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.912 CIFunHouse[2400:489970] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:16.955 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:16.996 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.038 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.080 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.122 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.163 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.205 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.246 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.288 CIFunHouse[2400:489970] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.330 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.371 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.415 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.456 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.496 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.539 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.580 CIFunHouse[2400:489895] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:17.622 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.664 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.705 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.746 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.788 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.830 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.873 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.914 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:17.956 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:17.997 CIFunHouse[2400:489913] 0.501961, 0.941176, 0.831373 2015-05-23 15:58:18.038 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.080 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.122 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.163 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.206 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.248 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.289 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.330 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.372 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.413 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.459 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.497 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.538 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.580 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.622 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.663 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.706 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.747 CIFunHouse[2400:489895] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.789 CIFunHouse[2400:489895] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.830 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.868 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:18.907 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.949 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:18.990 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.044 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.091 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.134 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.173 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:19.213 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.254 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:19.298 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:19.337 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:19.377 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:19.415 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:19.455 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:19.498 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:19.540 CIFunHouse[2400:489913] 0.564706, 0.917647, 0.831373 2015-05-23 15:58:19.588 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:19.630 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.674 CIFunHouse[2400:489913] 0.501961, 0.380392, 0.898039 2015-05-23 15:58:19.719 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.763 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.806 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.851 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:19.902 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:19.960 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:20.016 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:20.073 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:20.139 CIFunHouse[2400:489913] 0.000000, 0.882353, 0.898039 2015-05-23 15:58:20.198 CIFunHouse[2400:489913] 0.000000, 0.882353, 0.898039 2015-05-23 15:58:20.253 CIFunHouse[2400:489913] 0.000000, 0.882353, 0.898039 2015-05-23 15:58:20.316 CIFunHouse[2400:489913] 0.313726, 0.894118, 0.831373 2015-05-23 15:58:20.389 CIFunHouse[2400:489913] 0.313726, 0.894118, 0.831373 2015-05-23 15:58:20.472 CIFunHouse[2400:489913] 0.313726, 0.894118, 0.831373 2015-05-23 15:58:20.554 CIFunHouse[2400:489913] 0.313726, 0.894118, 0.831373 2015-05-23 15:58:20.631 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:20.714 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:20.784 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:20.839 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:20.887 CIFunHouse[2400:489913] 0.690196, 0.309804, 0.819608 2015-05-23 15:58:20.935 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 2015-05-23 15:58:20.981 CIFunHouse[2400:489913] 0.752941, 0.858824, 0.890196 
0
source

I worked on this for a while, but never got kCIFormatARGB8 to work. Another poster said kCIFormatARGBf does not work on iOS, so I tried kCIFormatRGBAh .

kCIFormatRGBAh is strange: RGBA data is packed as 16-bit floats ("half-fields"). C does not have a built-in half-type, and you must rely on compiler-specific data types. Fortunately, both gcc and clang seem to support type like __fp16 .

 // img is input histogramFilter = [CIFilter filterWithName:@"CIAreaHistogram" keysAndValues:@"inputScale", @1, @"inputCount", @256, nil]; CIVector *extent = [[CIVector alloc] initWithCGRect:img.extent]; [histogramFilter setValue:extent forKey:@"inputExtent"]; [histogramFilter setValue:img forKey:kCIInputImageKey]; CIImage *histImg = histogramFilter.outputImage; int rowBytes = 256 * 4; // ARGB has 4 components. __fp16 byteBuffer[rowBytes]; // Buffer to render into rowBytes *= 2; //__fp16 is 2 bytes EAGLContext *myEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; NSDictionary *options = @{ kCIContextWorkingColorSpace : [NSNull null] }; CIContext *ctx = [CIContext contextWithEAGLContext:myEAGLContext options:options]; [ctx render:histImg toBitmap:byteBuffer rowBytes:rowBytes bounds:[histImg extent] format:kCIFormatRGBAh colorSpace:nil]; for (int i = 0; i < 256; i++) { const __fp16* pixel = &byteBuffer[i*4]; NSLog(@"%d: %f, %f, %f, %f\n", i, (float)pixel[0], (float)pixel[1], (float)pixel[2], (float)pixel[3]); } 

I do not think this will work on the simulator because the simulator does not support kCIFormatRGBAh.

0
source

There is an undocumented CIAreaHistogram callData output method that may be useful.

0
source

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


All Articles