mattobob
mattobob

Reputation: 865

random matrix with restrictions

I would like to generate a random matrix, it's elements should be only 1s or 0s, I have to pass quite a lot of restrictions like:

  1. number of 0s equal numbers of 1s or 70% 0s 30% 1s
  2. most of the 0 in a corner or in the central part of the matrix
  3. 0s avoid common patterns like diagonals or rectangles

The purpose is to give a graphic representation like a chessboard, many matrixes have to be generated randomly and shown to the user.

Therefore I used a cv::Mat from opencv2 which is exactly what i need for the graphic representation, but it is not comfortable on random restrictions; my code:

Mat mean = Mat::zeros(1,1,CV_32FC1);
Mat sigma= Mat::ones(1,1,CV_32FC1);
Mat resized = Mat(300,300,CV_32FC3);
Mat thr;
lotAreaMat = Mat(lotAreaWidth,lotAreaHeight,CV_32FC3);
randn(lotAreaMat,  mean, sigma);
resize(lotAreaMat, resized, resized.size(), 0, 0, cv::INTER_NEAREST);

Mat grey;// = resized.clone();
cvtColor(resized,grey,CV_RGB2GRAY);
threshold(grey,thr,0.2,255,THRESH_BINARY_INV);

the problem here is that I have no idea how to define a random generator pattern, some ideas?

The graphics representation of those matrixes look like AR-Markers!

Upvotes: 2

Views: 156

Answers (1)

francis
francis

Reputation: 9817

There is little chance to find exactly the function you want in opencv. You may have to access pixels one by one and use rand() http://www.cplusplus.com/reference/cstdlib/rand/

Here is a starting point, drawing something like a disk of random points :

#include<iostream>
#include<cmath>

#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
using namespace std;
using namespace cv;

uchar getrandom(double probazero){
    int bla=rand();
    if(probazero*RAND_MAX>bla){
        return 0;
    }
    return 255;
}

int main()

{
    srand(time(NULL));
    int sizex=420;
    int sizey=420;
    Mat A = Mat(sizex,sizey,CV_8UC1);

    double dx=2.0/A.cols;
    double dy=2.0/A.rows;
    double y=-dy*(A.rows*0.5);
    uchar *input = (uchar*)(A.data);
    for(int j = 0;j < A.rows;j++){
        double x=-dx*(A.cols*0.5);
        for(int i = 0;i < A.cols;i++){
                            // x*x+y*y is square of radius
            input[A.step * j + i ]=getrandom(x*x+y*y) ;
            x+=dx;
        }
        y+=dy;
    }

    imwrite("out.png",A );
    A.release();

    return 0;
}

To compile :

 gcc -fPIC main3.cpp -o main3 -lopencv_highgui -lopencv_imgproc -lopencv_core -I /usr/local/include

Bye,

Francis

Upvotes: 1

Related Questions