烟囱通过简单传递会扭曲颜色值

问题描述

我写了一个rgbToHSV香石来转换图像中的像素;但是,它不能正常工作。我将其范围缩小为RGB值一路失真。

为简化代码,我将其更改为简单的直通过滤器。

我已经通过了1280 x 720张全彩色的图像,然后在穿过烟囱之前和之后的位置(100,100)处对像素颜色进行了采样。

以下是结果:

红色 之前:pixelColor :: :: rgba:1.0:0.0:0.0:1.0 之后:pixelColor :: :: rgba:1.0:0.07450980392156863:0.0:1.0

绿色 之前:pixelColor :: rgba:0.0:1.0:0.0:1.0 之后:pixelColor :: :: rgba:0.0:0.984313725490196:0.0:1.0

蓝色 之前:pixelColor :: :: rgba:0.0:0.0:1.0:1.0 之后:pixelColor :: :: rgba:0.0:0.1803921568627451:1.0:1.0

如您所见,红色和绿色略有失真,但是蓝色严重失真。

我已经保存了输出文件并检查了颜色,并且滤镜肯定在改变颜色。

任何对为什么简单的直通会改变颜色的见解都将受到赞赏。

简化的直通过滤器:

kernel vec4 rgbToHsv( __sample rgb) {
  return rgb;
}

这是使用香菜籽的CIFilter:

class RgbToHsvFilter: CIFilter {
  @objc dynamic var inputimage: CIImage?

  
  private lazy var kernel: CIColorKernel? = {
    guard let path = Bundle.main.path(forResource: "RgbToHsv",ofType: "cikernel"),let code = try? String(contentsOfFile: path) else { fatalError("Failed to load RgbToHsv.cikernel from bundle") }
    let kernel = CIColorKernel(source: code)
    return kernel
  }()

  override public var outputimage: CIImage! {
    get {
      if let inputimage = self.inputimage {
        
        let args = [inputimage as AnyObject]
        return self.kernel?.apply(extent: inputimage.extent,arguments: args)
      } else {
        return nil
      }
    }
  }
}

调用过滤器

    let rgbToHsvFilter = RgbToHsvFilter()
    let currentCI = CIImage(cgImage: colorImage!.cgImage!)
    rgbToHsvFilter.setValue(currentCI,forKey: kCIInputimageKey)
    
    if let hsvImage = rgbToHsvFilter.outputimage {
      if let image = cgImage(from: hsvImage) {
        let newImage = UIImage(cgImage: image as! CGImage)
        
        
        let _ = newImage.getPixelColor(pos: pixelPoint)
     
        //UIImageWritetoSavedPhotosAlbum(newImage,self,#selector(image(_:didFinishSavingWithError:contextInfo:)),nil)
      }
    }
  }

getPixelColor方法,其中CGPoint设置为(100,100)。我以为这个问题可能是由于打印出来的颜色中可能出现的虚假陈述而引起的,但是我检查了实际的输出图像,并且滤镜改变了图像的颜色:

  func getPixelColor(pos: CGPoint) -> UIColor {
    
    let pixelData = self.cgImage!.dataProvider!.data
    let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
    
    let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4
    
    let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
    let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
    let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
    let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)
    
    print("pixelColor :: rgba : \(r) : \(g) : \(b) : \(a)")
    
    return UIColor(red: r,green: g,blue: b,alpha: a)
  }

和cgImage(已编辑):


  func cgImage(from ciImage: CIImage) -> CGImage? {
      let context = CIContext(options: nil)
      return context.createCGImage(ciImage,from: ciImage.extent)
  }

解决方法

因此CIContext在方法cgImage中未正确初始化。

这是更正的方法:

int main()
{
    srand(time(NULL));
    priority_queue<long long int> pQueueInts;
    const int TRIALS = 1000000;
    for (int i = 0; i < TRIALS; i++)
    {
        long long int holder = randomNumber();
        pQueueInts.push(holder);
    }

    cout << pQueueInts.top();
    for (int i = 0; i < TRIALS / 2; i++)
        pQueueInts.pop();

    cout << pQueueInts.top();

    for (int i = 0; i < (TRIALS / 2) - 1; i++)
        pQueueInts.pop();

    cout << pQueueInts.top();
}

long long int randomNumber()
{
    bool found = false;
    long long int counter = 0;
    while (found == false)
    {
        int roll = rand() % 500;
        if (roll == 1)
        {
            roll = rand() % 500;
            if (roll == 2)
                found = true;
        }
        counter++;
    }

    found = false;

    while (found == false)
    {
        int roll = rand() % 100;
        if (roll == 3)
        {
            roll = rand() % 250;
            if (roll == 4)
                found = true;
        }
        counter++;
    }

    found = false;

    while (found == false)
    {
        int roll = rand() % 530;
        if (roll == 5)
        {
            roll = rand() % 400;
            if (roll == 6)
                found = true;
        }
        counter++;
    }

    return counter / 3;
}