2013-02-14 34 views
6

Bir IplImage'ın Pixel by Pixel'e erişmeye çalışıyorum. Java ve İşleme kullanıyorum ve bazen piksele piksele erişmem gerekiyor. Ben şimdiye kadar bu yaptık ama ben neyin yanlış olduğunu bilmiyorum:IplImage Piksel Erişimi JavaCV

public IplImage PImageToIplImage(PImage imageSrc) 
    { 
     IplImage imageDst; 
     if(imageSrc.format==RGB) 
     { 
      imageDst = IplImage.create(imageSrc.width, imageSrc.height, IPL_DEPTH_8U, 3); 
      ByteBuffer imagePixels=imageDst.getByteBuffer(); 
      int locPImage, locIplImage, x, y; 
      for(y=0; y<imageSrc.height; y++) 
       for(x=0; x<imageSrc.width; x++) 
       { 
        locPImage = x + y * width; 
        locIplImage=y*imageDst.widthStep()+3*x; 
        imagePixels.put(locIplImage+2, (byte)(red(imageSrc.pixels[locPImage]))); 
        imagePixels.put(locIplImage+1, (byte)(green(imageSrc.pixels[locPImage]))); 
        imagePixels.put(locIplImage, (byte)(blue(imageSrc.pixels[locPImage]))); 
       } 
     } 
} 

Karlphilip sugestion sonra, hala işi doens't, bu geldi. Ben göstermeye çalıştığınızda, bana bir nullPointer istisna verir:

imageDst = IplImage.create(imageSrc.width, imageSrc.height, IPL_DEPTH_8U, 3); 
CvMat imagePixels = CvMat.createHeader(imageDst.height(), imageDst.width(), CV_32FC1); 
cvGetMat(imageDst, imagePixels, null, 0); 
int locPImage, x, y; 
for(y=0; y<imageSrc.height; y++) 
    for(x=0; x<imageSrc.width; x++) 
    { 
     locPImage = x + y * width; 
     CvScalar scalar = new CvScalar(); 
     scalar.setVal(0, red(imageSrc.pixels[locPImage])); 
     scalar.setVal(1, green(imageSrc.pixels[locPImage])); 
     scalar.setVal(2, blue(imageSrc.pixels[locPImage])); 
     cvSet2D(imagePixels, y, x, scalar); 
    } 
    imageDst = new IplImage(imagePixels); 
+0

Ne hat istisna tetikler? – karlphillip

cevap

7

JavaCV her pikseli üzerinde yineleme için en hızlı yoldur:

ByteBuffer buffer = image.getByteBuffer(); 

for(int y = 0; y < image.height(); y++) { 
    for(int x = 0; x < image.width(); x++) { 
     int index = y * image.widthStep() + x * image.nChannels(); 

     // Used to read the pixel value - the 0xFF is needed to cast from 
     // an unsigned byte to an int. 
     int value = buffer.get(index) & 0xFF; 

     // Sets the pixel to a value (greyscale). 
     buffer.put(index, value); 

     // Sets the pixel to a value (RGB, stored in BGR order). 
     buffer.put(index, blue); 
     buffer.put(index + 1, green); 
     buffer.put(index + 2, red); 
    } 
} 
+0

Yapmaya çalıştığım şey bu, ama işe yaramıyor (bir piksel okumak gayet iyi, ancak yazmıyor). Örneğinizde, bir RGB değerini nasıl koyabilirim? –

+0

Bir RGB örneği ekledim. – ajshort

+0

Teşekkürler. Yaptığım tam olarak bu, ama işe yaramıyor. Yukarıdaki koda bakar mısınız ve yanlış mı görüyorum? Bu ilk kod. Teşekkürler. –

1

Aşağıdaki kod diskten bir görüntü yükler ve görüntünün piksel üzerinde yineleme tarafından bir gri tonlama dönüştürmesi gerçekleştirir:

IplImage image = cvLoadImage("pipeline.png", CV_LOAD_IMAGE_COLOR); 
    if (image == null) 
    { 
     System.out.println("Erro ao carregar imagem!"); 
     return; 
    } 

    double r, g, b; 
    r = g = b = 0.0;  

    CvMat mtx = CvMat.createHeader(image.height(), image.width(), CV_32FC1); 
    cvGetMat(image, mtx, null, 0); 

    System.out.println(mtx.rows() + "x" + mtx.cols()); 

    for (int i = 0; i < mtx.rows(); i++) 
    { 
     for (int j = 0; j < mtx.cols(); j++) 
     { 
      CvScalar rgb = cvGet2D(mtx, i, j); 
      r = rgb.val(0); 
      g = rgb.val(2); 
      b = rgb.val(1); 

      double gray = (r + g + b)/3; 

      CvScalar scalar = new CvScalar(); 
      scalar.setVal(0, gray); 
      scalar.setVal(1, gray); 
      scalar.setVal(2, gray); 
      cvSet2D(mtx, i, j, scalar); 
     } 
    }   

    IplImage result = new IplImage(mtx); 
    cvSaveImage("manual_gray.png", result); 

    cvReleaseImage(image); 

Yeni bir CvMat oluşturmanın en iyi yaklaşım olduğundan emin değilsiniz, ama javacv'da çalışmayı bildiğim tek yol budur.

DÜZENLEME:

Maalesef OpenCV, like PImage ait olmayan veri türlerini kullanmak, ama ne yaptığını taklit etmek elimden geleni yaptım.

// Create a black image 
    IplImage imageDst = IplImage.create(imageSrc.width(), imageSrc.height(), IPL_DEPTH_8U, 3); 

    // Create a temporary mat to iterate over it's pixels 
    CvMat imagePixels = CvMat.createHeader(imageDst.height(), imageDst.width(), CV_32FC1); 

    // Copy black image to temporary mat 
    cvGetMat(imageDst, imagePixels, null, 0); 

    int x, y; 
    for(y=0; y<imageSrc.height(); y++) 
     for(x=0; x<imageSrc.width(); x++) 
     { 
      // At this point you tried to do: locPImage = x + y * width; 
      // but I think you might have mistaken for: locPImage = y + x * width; 

      //... 
     } 
     imageDst = new IplImage(imagePixels); 
+0

Çok teşekkürler. Bunu deneyeceğim. Gösterdiğim gibi, benzer bir yaklaşım kullanarak değeri okumayı başardım. Bunu daha sonra deneyeceğim ama şimdiden teşekkürler;) –

+0

Teşekkür etmenize gerek yok, sadece cevaba oy verebilirsiniz :) – karlphillip

+0

Denedim, ama benimle çalışmıyor. Görüntü null, nasıl bilmiyorum:/ –