opencv java修改像素值

Zyp*_*987 1 java opencv image-processing

我一直在尝试在 opencv java 中转换一些 opencv C++ 代码,但似乎无法让像素分割正常工作。我拿了一个 meanshiftsegmented mat,然后转换为灰度,然后转换为 32F。

然后我将最下采样然后上采样的图像(由灰色均值偏移垫组成)与原始灰色均值偏移垫进行比较。

我已经阅读了Using get() and put() to access pixel values in OpenCV for Java

但是,它和其他类似的东西不起作用。我收到的错误消息是无效的垫子类型 5。但是,即使我能够看到显着图,我也肯定这是错误的。这是因为当我在 C++ 中传入图像 001.jpg 时,我应该看到原始图像 + 对象周围的红色方块。在java中,我只看到最后的原始图像。

笔记 :

AbstractImageProvider.deepCopy(AbstractImageProvider.matToBufferedImage(Saliency),disp);

是一个 API 调用,当我尝试显示原始垫、meanShift 垫和灰色 meanShift 垫时有效。它无法显示显着性。

C++

我只做了一个通道拆分,因为我正在测试其他颜色空间,但是在 java 中我只想使用灰度。

  input = MeanShift.clone();
  input.convertTo(input, CV_32F);

  for(int i = 0; i < Pyramid_Size; i++){DS_Pyramid[i] = input.clone();}

  for (int i = 0; i < Pyramid_Size; i++){ 
    for (int k = 0; k <= i; k++){ // Why don't I just downsamplex3 a copy of MeanShift.clone then upsamplex3 that same one? ...
      pyrDown (DS_Pyramid[i], DS_Pyramid[i], Size(DS_Pyramid[i].cols/2, DS_Pyramid[i].rows/2));
      US_Pyramid[i] = DS_Pyramid[i].clone();
    }
    for (int j = 0; j <= i; j++){
      pyrUp (US_Pyramid[i], US_Pyramid[i], Size(US_Pyramid[i].cols*2, US_Pyramid[i].rows*2));
    }
  }

  top = US_Pyramid[Pyramid_Size - 1].clone(); // most down sampled layer, up sampled.
  split(top, top_chs);
  split(input.clone(), meanShift_chs); // split into channels result
  split(input.clone(), sal_chs); // holder to use for compare

  float top_min = 1.0;
  float ms_min = 1.0;
  for (int i = 0; i < top.rows; i++){   // find the smallest value in both top and meanShift
    for (int k = 0; k < top.cols; k++){ // this is so you can sub out the 0 with the min value
      for (int j = 0; j < top.channels(); j++){ // later on
    float a = top_chs[j].at<float>(i,k);
    float b = meanShift_chs[j].at<float>(i,k);
    if (a < top_min && a >= 0) {top_min = a;} // make sure you don't have a top_min of zero... that'd be bad.
    if (b < ms_min && b >= 0)  { ms_min = b;}
      }
    }
  }

  for (int i = 0; i < top.rows; i++){
    for (int k = 0; k < top.cols; k++){
      for (int j = 0; j < top.channels(); j++){
    float a,b,c;
    a = top_chs[j].at<float>(i,k);
    b = meanShift_chs[j].at<float>(i,k);

    if (a <= 0){a = top_min;} // make sure you don't divide by zero
    if (b <= 0){b = ms_min;} // make sure you really don't divide by zero
    if (a <= b){c = 1.0 - a/b;}
    else {c = 1.0 - b/a;}

    // c = sqrt(c); // makes stuff more salient, but makes noise pop out too
    sal_chs[j].at<float>(i,k) = c;
      }
    }
  }
  merge(sal_chs, Saliency); // combine into saliency map
  imshow("saliency", Saliency);
Run Code Online (Sandbox Code Playgroud)

爪哇

    MeanShift = inputImage.clone();

    Imgproc.pyrMeanShiftFiltering(MeanShift, MeanShift, MeanShift_spatialRad, MeanShift_colorRad);
    Imgproc.cvtColor(MeanShift, MeanShift, Imgproc.COLOR_BGR2GRAY);

    MeanShift.convertTo(MeanShift, CvType.CV_32F);                 // 32F between 0 - 1. ************** IMPORTANT LINE

    for (int i = 0; i < PyrSize; i++){
        DS_Pyramid.add(new Mat());
        UP_Pyramid.add(new Mat());
    }

    for (int i = 0; i < PyrSize; i++){    
        DS_Pyramid.set(i, MeanShift);
    }       

    for (int i = 0; i < PyrSize; i++){
        for(int k = 0; k <= i; k++){                               // At 0 is downsampled once, second twice, third 3 times. 
        Imgproc.pyrDown(DS_Pyramid.get(i), DS_Pyramid.get(i)); // pyrDown by default img.width / 2 img height / 2
        Mat a = new Mat();                                     // save the sampled down at i
        a = DS_Pyramid.get(i);                            
        UP_Pyramid.add(a);
        }
        for (int j = 0; j <= i; j++){
        Imgproc.pyrUp(UP_Pyramid.get(i),UP_Pyramid.get(i));    
        }                                                          
    }
    top = UP_Pyramid.get(PyrSize-1);
    bot = MeanShift.clone();
    Saliency = MeanShift.clone();


    //http://answers.opencv.org/question/5/how-to-get-and-modify-the-pixel-of-mat-in-java/
    //http://www.tutorialspoint.com/java_dip/applying_weighted_average_filter.htm

    for (int i = 0; i < top.rows(); i++){
        for (int j = 0; j < top.cols(); j++){
        int index = i * top.rows() + j;

        float[] top_temp = top.get(i, j);
        float[] bot_temp  = bot.get(i,j);
        float[] sal_temp = bot.get(i,j);

        if (top_temp[0] <= bot_temp[k]){sal_temp[0] = 1.0f - (top_temp[0]/bot_temp[0]);}
        else                           {sal_temp[0] = 1.0f - (bot_temp[0]/top_temp[0]);}

        Saliency.put(i,j, sal_temp);
        }
    }

    AbstractImageProvider.deepCopy(AbstractImageProvider.matToBufferedImage(Saliency),disp);
Run Code Online (Sandbox Code Playgroud)

Cra*_*akC 5

经过大量搜索,找到了一个简单有效的解决方案。这可能会帮助您克服错误无效的垫子类型 5

代码:

Mat img = Highgui.imread("Input.jpg"); //Reads image from the file system and puts into matrix
int rows = img.rows(); //Calculates number of rows
int cols = img.cols(); //Calculates number of columns
int ch = img.channels(); //Calculates number of channels (Grayscale: 1, RGB: 3, etc.)

for (int i=0; i<rows; i++)
{
    for (int j=0; j<cols; j++)
    {
        double[] data = img.get(i, j); //Stores element in an array
        for (int k = 0; k < ch; k++) //Runs for the available number of channels
        {
            data[k] = data[k] * 2; //Pixel modification done here
        }
        img.put(i, j, data); //Puts element back into matrix
    }
}
Highgui.imwrite("Output.jpg", img); //Writes image back to the file system using values of the modified matrix
Run Code Online (Sandbox Code Playgroud)

注意:在线任何地方都没有提到的重要一点是该方法put不会将像素写入Input.jpg. 它只是更新矩阵的值img。因此,上面的代码不会改变输入图像中的任何内容。为了产生可见的输出,img需要将矩阵写入文件,即Output.jpg在这种情况下。此外,使用img.get(i, j)似乎是处理矩阵元素的更好方法,而不是使用上面接受的解决方案,因为这有助于以更好的方式可视化和处理图像矩阵,并且不需要大量连续的内存分配。