首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IplImage像素访问JavaCV

IplImage像素访问JavaCV
EN

Stack Overflow用户
提问于 2013-02-14 22:46:42
回答 2查看 9.3K关注 0票数 6

我正在尝试访问IplImage的一个像素一个像素。我正在使用Java和Processing,有时我需要逐个像素地访问。到目前为止,我已经做到了这一点,但我不知道哪里出了问题:

代码语言:javascript
复制
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建议后,我来到了这个,仍然不工作。当我尝试显示时,它给了我一个nullPointer异常:

代码语言:javascript
复制
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); 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-15 06:25:13

在JavaCV中迭代每个像素的最快方法是:

代码语言:javascript
复制
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);
    }
}
票数 7
EN

Stack Overflow用户

发布于 2013-02-15 00:14:20

下面的代码从磁盘加载图像,并通过迭代图像的像素来执行灰度转换:

代码语言:javascript
复制
    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); 

我不确定创建一个新的CvMat是否是最好的方法,但这是我所知道的在javacv中工作的唯一方法。

编辑

不幸的是,您使用的数据类型不是来自OpenCV、like PImage,但我已经尽了最大努力模拟您正在做的事情。

代码语言:javascript
复制
    // 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); 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14877383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档