2013-02-14 2 views
6

J'essaie d'accéder à Pixel by Pixel d'une image IplImage. Im en utilisant Java et le traitement, et parfois j'ai besoin d'accéder pixel par pixel. Je l'ai fait jusqu'à présent, mais je ne sais pas ce qui ne va pas: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]))); 
       } 
     } 
} 

Après Karlphilip Sugestion, je suis venu à cela, doens't encore du travail. Lorsque je tente de montrer, il me donne une exception NullPointer:

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

Quelle ligne déclenche l'exception? – karlphillip

Répondre

7

Le meilleur moyen de parcourir chaque pixel JavaCV est:

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

C'est ce que j'essaie de faire, mais ça ne marche pas (lire un pixel c'est bien, mais écrire ça non). Dans votre exemple, comment mettre une valeur RVB? –

+0

J'ai ajouté un exemple RVB. – ajshort

+0

Merci. C'est exactement ce que j'ai fait, mais ça ne marche pas. Pouvez-vous s'il vous plaît regarder le code ci-dessus et voir ce que je fais mal? C'est le premier code. Merci. –

1

Le code suivant charge une image à partir du disque et effectue une conversion en niveaux de gris par itérer sur les pixels de l'image:

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

Je ne sais pas si la création d'un nouveau CvMat est la meilleure approche, mais c'est la seule façon que je sais de travailler dans javacv.

EDIT:

Malheureusement, vous utilisez des types de données qui ne sont pas de OpenCV, like PImage, mais je fait de mon mieux pour simuler ce que vous faites.

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

Merci beaucoup. Je vais essayer ça. J'ai réussi à lire la valeur en utilisant une approche similaire, comme je l'ai montré. Je vais essayer cela plus tard, mais merci d'avance;) –

+0

Il n'y a pas besoin de merci, vous pouvez simplement voter la réponse :) – karlphillip

+0

Je l'ai essayé, mais ça ne fonctionne pas avec moi. L'image est nulle, je ne sais pas comment:/ –