Высокая производительность при обработке пикселей - PullRequest
0 голосов
/ 28 августа 2018

Мне нужно сделать быструю функцию для определения размера областей определенного цвета. Функция, которую я написал, но не могу получить скорость обработки, которую я имею для той же функции в Objective C.

После нескольких дней оптимизации на iPhone 7Plus и изображении 2048x2048 поиск 256 зон занимает 1,04 с на ObjectiveC и 2,5 с на Swift.

Что я пропустил и где можно оптимизировать код Swift?

@IBAction func allZonesOpt(_ sender: Any) {
        let startDate = Date()

        let image : UIImage = UIImage(named:"idx.png")!

        let cgImage : CGImage = image.cgImage!
        guard let pixelData = CGDataProvider(data: (cgImage.dataProvider?.data)!)?.data else {
            return
        }
        let data = CFDataGetBytePtr(pixelData)!
        let numberOfComponents:Int = 4

        let imageWidth = Int(image.size.width)
        let imageHeight = Int(image.size.height)
        let bytesPerRow = imageWidth * numberOfComponents


        let rangeOne = 0..<Int(image.size.height)
        let rangeTwo = 0..<Int(image.size.width)
        var arrayWithZones = [(Int, Int)]()

        for colorRed:UInt8 in 0...255 {
          //  autoreleasepool {
                let colorR = colorRed
                let colorG = 0
                let colorB = 0


                var minx:Int = imageWidth
                var miny:Int = imageHeight
                var maxx:Int = 0
                var maxy:Int = 0
                let startDateFor = Date()
            for y in rangeOne {
                for x in rangeTwo {
                        let pixelData = (bytesPerRow * y) + x * numberOfComponents

                        if data[pixelData] == colorR && data[pixelData + 1] == colorG && data[pixelData+2] == colorB{
                            if minx > x{
                                minx = x
                            }
                            if miny > y{
                                miny = y
                            }
                            if maxx < x{
                                maxx = x
                            }
                            if maxy < y{
                                maxy = y
                            }
                        }
                    }
                }
                let methodFinishFor = Date()
                let timeIntervalFor = methodFinishFor.timeIntervalSince(startDateFor)
                print(" time execution = \(timeIntervalFor)")
                arrayWithZones.append((maxx - minx, maxy - miny))
               // let finalSize = CGSize(width: maxx - minx, height: maxy - miny)
               // print("final = \(finalSize)")
           // }
        }


        let methodFinish = Date()
        let timeInterval = methodFinish.timeIntervalSince(startDate)
        resultLabel.text = " time execution = \(timeInterval)"
        print(" time execution = \(timeInterval)")
        print("atFinal = \(arrayWithZones)");
    }

Objective-C:

- (IBAction)allZonesAsSwift:(id)sender {
    NSDate *methodStart = [NSDate date];

    UIImage *image = [UIImage imageNamed:@"idx.png"];

    //static rawData
    CGImageRef imageRef = [image CGImage];
    unsigned int width = (unsigned int)CGImageGetWidth(imageRef);
    unsigned int height = (unsigned int)CGImageGetHeight(imageRef);

    int bytesPerPixel = 4;
    int bytesPerRow = bytesPerPixel * width;

    CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
    const unsigned char * rawData =  CFDataGetBytePtr(data);

    unsigned int minx = image.size.width;
    unsigned int miny = image.size.height;
    unsigned int maxx = 0;
    unsigned int maxy = 0;

    unsigned char colorR = 0;
    unsigned char colorG = 0;
    unsigned char colorB = 0;

    NSMutableArray *arrayWithZones = [NSMutableArray<NSValue*> new];

    for (int colorRed = 0; colorRed < 256; colorRed ++) {
        colorR = (unsigned char)colorRed;

        minx = (unsigned  int)image.size.width;
        miny = (unsigned int)image.size.height;
        maxx = 0;
        maxy = 0;
        NSDate *methodStartFor = [NSDate date];
        for (unsigned int y = height - 1; y; y--) {
            for (unsigned int x = width - 1; x; x--) {
                unsigned int byteIndex = (bytesPerRow * y) + x * bytesPerPixel;

                if (rawData[byteIndex] == colorR && rawData[byteIndex + 1] == colorG && rawData[byteIndex + 2] == colorB) {
                    minx = x < minx ? x : minx;
                    maxx = x > maxx ? x : maxx;
                    miny = y < miny ? y : miny;
                    maxy = y > maxy ? y : maxy;
                }
            }
        }

        NSDate *methodFinishFor = [NSDate date];
        NSTimeInterval executionTimeFor = [methodFinishFor timeIntervalSinceDate:methodStartFor];
        NSLog(@"executionTime Zone = %f", executionTimeFor);

        CGSize final = CGSizeMake(maxx - minx, maxy - miny);
        [arrayWithZones addObject:[NSValue valueWithCGSize:final]];
    }

    free(rawData);

    NSDate *methodFinish = [NSDate date];
    NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
    NSLog(@"color picker = %f", executionTime);
    _resultLabel.text = [NSString stringWithFormat:@"color picker = %f", executionTime];
    NSLog(@"final = %@", arrayWithZones);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...