IplImage Pixel Access JavaCV

匿名 (未验证) 提交于 2019-12-03 02:52:02

问题:

I'm trying to access Pixel by Pixel of an IplImage. Im using Java and Processing, and sometimes I need to access pixel by pixel. I've done this so far, but I don't know what's wrong:

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

After Karlphilip sugestion, I came to this, still doens't work. When I try to show, it gives me a nullPointer exception:

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

回答1:

The fastest way to iterate over each pixel in JavaCV is:

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


回答2:

The following code loads an image from the disk and performs a grayscale conversion by iterating over the pixels of the 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);  

Not sure if creating a new CvMat is the best approach, but it's the only way I know to work in javacv.

EDIT:

Unfortunately you use data types that are not from OpenCV, like PImage, but I did my best to simulate what you are doing.

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!