2013-02-14 11 views
6

Ich versuche Pixel für Pixel eines IplImage zuzugreifen. Ich benutze Java und Processing, und manchmal muss ich Pixel für Pixel zugreifen. Ich habe dies bisher getan, aber ich weiß nicht, was falsch ist:IplImage Pixel Access 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]))); 
       } 
     } 
} 

Nach Karlphilip sugestion kam ich dazu noch Arbeit doens't. Wenn ich versuche zu zeigen, gibt es mir eine Nullpointer-Ausnahme:

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

Welche Linie die Ausnahme auslöst? – karlphillip

Antwort

7

Der schnellste Weg, um jedes Pixel in JavaCV iterieren ist:

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

Das ist, was ich versuche zu tun, aber es funktioniert nicht (Lesen eines Pixels ist in Ordnung, aber schreiben ist es nicht). In Ihrem Beispiel, wie lege ich einen RGB-Wert? –

+0

Ich habe ein RGB-Beispiel hinzugefügt. – ajshort

+0

Danke. Genau das habe ich gemacht, aber es funktioniert nicht. Kannst du dir bitte den obigen Code ansehen und sehen, ob ich falsch liege? Es ist der erste Code. Vielen Dank. –

1

Der folgende Code ein Bild von der Festplatte geladen und führt eine Graustufen-Umwandlung von über die Pixel des Bildes iteriert:

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); 

Ich bin mir nicht sicher, ob das Erstellen eines neuen CvMat der beste Ansatz ist, aber es ist der einzige Weg, den ich kenne, um in javacv zu arbeiten.

EDIT:

Leider verwenden Sie Datentypen, die nicht von OpenCV sind, like PImage, aber ich habe mein Bestes zu simulieren, was Sie tun.

// 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

Vielen Dank. Ich werde es versuchen. Es gelang mir, den Wert mit einem ähnlichen Ansatz zu lesen, wie ich gezeigt habe. Ich werde das später versuchen, aber danke im Voraus;) –

+0

Es gibt keine Notwendigkeit, danke, können Sie einfach die Stimme abstimmen :) – karlphillip

+0

Ich habe es versucht, aber es funktioniert nicht mit mir. Das Bild ist null, ich weiß nicht wie:/ –

Verwandte Themen