我正在比较具有相同宽度和高度的两个图像之间的“颜色距离”,看它们有多相似 - 相似度的衡量标准只是逐个像素地比较它们,看看每个颜色通道的距离是多少彼此。
- (NSNumber*) calculateFitness:(NSImage*)currentImage
andDestinationImage:(NSImage*)destinationImage {
NSData *tiffData = [currentImage TIFFRepresentation];
NSBitmapImageRep *currentImageRep = [NSBitmapImageRep
imageRepWithData:tiffData];
NSData *destinationImageTiffData = [destinationImage TIFFRepresentation];
NSBitmapImageRep *destinationImageRep = [NSBitmapImageRep imageRepWithData:destinationImageTiffData];
long fitnessScore = 0;
for (int width = 0; width < currentImageRep.size.width; width++) {
for (int height = 0; height < currentImageRep.size.height; height++) {
NSColor *destinationColor = [destinationImageRep colorAtX:width y:height];
NSColor *currentColor = [currentImageRep.size.height colorAtX:width y:height];
CGFloat deltaRed = (currentColor.redComponent - destinationColor.redComponent) * 255;
CGFloat deltaGreen = (currentColor.greenComponent - destinationColor.greenComponent) * 255;
CGFloat deltaBlue = (currentColor.blueComponent - destinationColor.blueComponent) * 255;
fitnessScore += (deltaRed * deltaRed) +
(deltaGreen * deltaGreen) +
(deltaBlue * deltaBlue);
}
}
}
我在程序中多次调用此方法来比较数千个图像的适合度。我在仪器中注意到的是,生活的NSCalibratedRGBColor对象的数量不断增长,这是由于destinationColor
和currentColor
对象是使用上面的NSBitmapImageRep:colorAtX:y
创建的。最终,我的整个系统内存将被消耗。
那么 - 这是否有原因发生?我究竟做错了什么?有没有更有效的方法来获取我的图像的原始位图数据?
感谢
穆斯塔法
答案 0 :(得分:3)
使用原始位图数据可能会获得更好的性能。如果您浏览所有图像数据,NSBitmapImageRep的-colorAtX:y:
(和-getPixel:atX:y
)会非常慢。此外,所有分配的NSColors都将保留在自动释放池中,直到您的应用程序返回主循环。
unsigned char *currentData = [currentImageRep bitmapData];
unsigned char *destinationData = [destinationImageRep bitmapData];
NSUInteger width = [currentImageRep pixelWidth];
NSUInteger height = [currentImageRep pixelHeight];
NSUInteger currentBytesPerRow = [currentImageRep bytesPerRow];
NSUInteger destBytesPerRow = [destinationImageRep bytesPerRow];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned char *srcPixel = currentData + ((x * 4) + (y * currentBytesPerRow));
unsigned char *destPixel = destinationData + ((x * 4) + (y * destBytesPerRow));
char sr, sg, sb;
char dr, dg, db;
sr = *srcPixel;
sg = *(srcPixel + 1);
sb = *(srcPixel + 2);
dr = *destPixel;
dg = *(destPixel + 1);
db = *(destPixel + 2);
CGFloat deltaRed = (sr - dr);
CGFloat deltaGreen = (sg - dg);
CGFloat deltaBlue = (sb - db);
fitnessScore += (deltaRed * deltaRed) +
(deltaGreen * deltaGreen) +
(deltaBlue * deltaBlue);
}
}
我写了https://medium.com/@iainx/fast-colour-analysis-d8b6422c1135来进行快速颜色分析,这是我发现的事情之一。