2013-02-14 12 views
6

Próbuję uzyskać dostęp do Pixel by Pixel z IplImage. Używam Java i Processing, a czasami potrzebuję dostępu do pikseli po pikselu. Robiłem to tak daleko, ale nie wiem, co się stało: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]))); 
       } 
     } 
} 

Po Karlphilip sugestion, doszedłem do tego, nadal doens't pracy. Kiedy próbuję pokazać, że daje mi wyjątek 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

Co linia wyzwala wyjątek? – karlphillip

Odpowiedz

7

Najszybszym sposobem iteracyjne nad każdego piksela w JavaCV jest:

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

To właśnie próbuję zrobić, ale to nie działa (czytanie piksela jest w porządku, ale pisanie go nie jest). W twoim przykładzie, jak umieścić wartość RGB? –

+0

Dodałem przykład RGB. – ajshort

+0

Dzięki. Dokładnie to zrobiłem, ale to nie działa. Czy możesz spojrzeć na powyższy kod i zobaczyć, czy robię źle? To pierwszy kod. Dzięki. –

1

Poniższy kod ładuje obraz z dysku i wykonuje szarości konwersja przez iteracja ciągu pikseli obrazu:

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

Nie jestem pewien, czy tworzenie nowego CvMat jest najlepszym podejściem, ale jest to jedyny sposób, w jaki wiem, aby pracować w javacv.

EDIT:

Niestety używać typów danych, które nie są z OpenCV, like PImage, ale starałem się symulować, co robisz.

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

Wielkie dzięki. Spróbuję tego. Udało mi się odczytać wartość za pomocą podobnego podejścia, jak pokazałem. Spróbuję później, ale dziękuję z góry;) –

+0

Nie ma potrzeby podziękowań, możesz po prostu oddać głos na odpowiedź :) – karlphillip

+0

Próbowałem, ale to nie działa ze mną. Obraz ma wartość zerową, nie wiem jak:/ –

Powiązane problemy