Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
368 views
in Technique[技术] by (71.8m points)

java - OpenCV pyrMeanShiftFilter in Processing--problems with matrix

I'm trying to use the Mean Shift Function from OpenCV inside a program called Processing, which is a language based on Java. So far, I know that the function requires two mat and two double, [ pyrMeanShiftFiltering( Mat, Mat, Double, Double) ] and the mat needs to be 8 bits and 3 channels. But, when I run it, it only seems to work for the upper 3/4 th of the image and cuts out the rest.

Does anyone know how to get this function to run on the whole image?

sample image: cat.jpg

import gab.opencv.*;
import java.nio.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Core; 

OpenCV opencv;
Imgproc imgproc;

PImage canny;
PImage src, out;
Mat one, two;
double a = 20.0;
double b = 10.0;

void setup() {
  src = loadImage("cat.jpg");
  size( 429, 360);

  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);  
  one = new Mat( width, height, CvType.CV_8UC3);
  two = new Mat( width, height, CvType.CV_8UC3);

  one = toMat(src);
  imgproc.pyrMeanShiftFiltering( one, two, a, b);
  out = toPImage(two); 
}

void draw() {
  image(out, 0, 0, width, height);
}

Mat toMat(PImage image) {  
  int w = image.width;  
  int h = image.height;  
  Mat mat = new Mat(h, w, CvType.CV_8UC3);  
  byte[] data8 = new byte[w*h*4];  
  int[] data32 = new int[w*h];  
  arrayCopy(image.pixels, data32);  
  ByteBuffer bBuf = ByteBuffer.allocate(w*h*4);  
  IntBuffer iBuf = bBuf.asIntBuffer();  
  iBuf.put(data32);  
  bBuf.get(data8);  
  mat.put(0, 0, data8);  
  return mat;
}  

 PImage toPImage(Mat mat) { 
  int w = mat.width(); 
  int h = mat.height(); 
  PImage image = createImage(w, h, ARGB); 
  byte[] data8 = new byte[w*h*4]; 
  int[] data32 = new int[w*h]; 
  mat.get(0, 0, data8); 
  ByteBuffer.wrap(data8).asIntBuffer().get(data32); 
  arrayCopy(data32, image.pixels); 
  return image;
} 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that you are using rows where the columns should be and columns where the rows should be. Check the Mat documentation for more information.

so, whenever you have this:

new Mat( width, height, CvType.CV_8UC3);

invert the order

new Mat( height, width, CvType.CV_8UC3);

Also, I notice that you have a 4 channel images (ARGB) and the toMat function also have 4 channels, but you create a Mat with only 3 CV_8UC3, you should use 4 CV_8UC4 (not sure in java), and beware, normally opencv uses is BGRA !! so you may need to mix the channels correctly.

I hope this helps you


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...