OpenCV mat.get(y,x)[0] == mat2.get(y,x)[0] returns true when false

asked 2019-08-11 13:54:16 -0500

generic27 gravatar image

updated 2019-08-12 09:36:33 -0500

Hello, I am comparing two mats coming from the same video source. I turned them into a gray scale image and I compared the RGB values of both using the get method with parameters (y,x), where the program draws a circle at the changed pixels. However, parts of the mat where there's a definite pixel change are not being recognized. The two images below illustrate what I am talking about.

image description

image description

The point of interest is at the black line on the right hand side of the video, where there is a new "arc" about to be formed, yet there is no hint of a single pixel change in that area for some reason.

Here is a snippet of my code which shows what I am doing:

//From a method called read doppler which takes the submat of a video then analyzes it according to the previous frame and current frame 
    Mat previousSource = getFrame(displayPointer - 1).submat((int) dopplerPoint1.y, (int) dopplerPoint2.y, (int) dopplerPoint1.x, (int) dopplerPoint2.x);

    Mat matSource = getFrame(displayPointer).submat((int) dopplerPoint1.y, (int) dopplerPoint2.y, (int) dopplerPoint1.x,(int) dopplerPoint2.x);

    Imgproc.cvtColor(matSource, matSource, Imgproc.COLOR_BGR2GRAY);
    Imgproc.cvtColor(previousSource, previousSource, Imgproc.COLOR_BGR2GRAY);

    double[][][] previousArray = new double[previousSource.width()][previousSource.height()][3];
    double[][][] nextArray = new double[matSource.width()][matSource.height()][3];

    outerLoop2: for (int x = 0; x < previousArray.length; x++) {
                innerLoop2: for (int y = 0; y < previousArray[0].length; y++) {
                    previousArray[x][y] = previousSource.get(y, x);
                    nextArray[x][y] = matSource.get(y, x);

    outerLoop: for (int x = 0; x < previousArray.length; x++) {
                double[] columnArray = new double[(int) matSource.height()];
                for (int filler = 0; filler < columnArray.length; filler++) {
                    columnArray[filler] = new Point(x, filler).y;

    innerLoop: for (int y = 0; y < previousArray[0].length; y++) {
    boolean compare = Arrays.equals(previousArray[x][y], nextArray[x][y]);

    if (!compare) {
   Point point = new Point(x,y);, point, 5,new Scalar(255, 255, 0), 1);

//Code then applies the submat onto the original video with the drawn points

Thank you in advance!

edit retag flag offensive close merge delete


All Mat types I am working with are CV8U_C3

generic27 gravatar imagegeneric27 ( 2019-08-11 14:25:42 -0500 )edit

and I compared the RGB values of both

please show us, what you tried, exactly. video signals contain noise, you probably need a more robust proprocessing / comparison.

berak gravatar imageberak ( 2019-08-12 00:53:19 -0500 )edit

Updated with relevant code

generic27 gravatar imagegeneric27 ( 2019-08-12 09:37:10 -0500 )edit
  1. throw away all of it (please stop thinking in for loops here)
  2. lookup opencv operations like threshold() and absdiff()
berak gravatar imageberak ( 2019-08-12 09:45:45 -0500 )edit

Hey there berak, I spent the day looking into those operations and better solutions in general, which led me to image subtraction in my case. Background subtraction in my use wasn't a valid solution because I needed more exact changes of pixels (which image subtraction provided). I have now been led to another issue which I will be posting later, but thank you for the guidance.

generic27 gravatar imagegeneric27 ( 2019-08-12 20:21:42 -0500 )edit