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

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 reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by sturkmen
close date 2020-10-13 14:05:15.846437


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