2016年6月14日 星期二

opencv case study -> 15 puzzle



先看 onCreate

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        Log.d(TAG, "Creating and setting view");
        mOpenCvCameraView = (CameraBridgeViewBase) new JavaCameraView(this, -1);
        setContentView(mOpenCvCameraView);
        mOpenCvCameraView.setCvCameraViewListener(this);
        mPuzzle15 = new Puzzle15Processor();
        mPuzzle15.prepareNewGame();
    }

Class JavaCameraView


This class is an implementation of the Bridge View between OpenCV and Java Camera. This class relays on the functionality available in base class and only implements required functions: connectCamera - opens Java camera and sets the PreviewCallback to be delivered. disconnectCamera - closes the camera and stops preview. When frame is delivered via callback from Camera - it processed via OpenCV to be converted to RGBA32 and then passed to the external callback for modifications if required.


透過 JavaCameraView(this,-1)   就可以抓到camera 的物件  mOpenCvCameraView

 使用setContentView可以在Activity中動態切換顯示的View,這樣

  • CameraBridgeViewBase .enableView()
  • SurfaceView is available
    • CameraBridgeViewBase  .setVisibility(SurfaceView.Visiable)
    • CameraBridgeViewBase  .setCvCameraViewListener(this)
就可以使用回调函数
  • onCameraViewStarted 
  • onCameraViewStopped


再看  Puzzle15Processor class

 public Puzzle15Processor() {
        mTextWidths = new int[GRID_AREA];  // GRID_AREA = GRID_SIZE * GRID_SIZE;
        mTextHeights = new int[GRID_AREA]; // GRID_SIZE  = 4

        mIndexes = new int [GRID_AREA];

        for (int i = 0; i < GRID_AREA; i++)
            mIndexes[i] = i;
    }



畫方格線

import org.opencv.core.Core;

就可以使用 Core

private void drawGrid(int cols, int rows, Mat drawMat) {
        for (int i = 1; i < GRID_SIZE; i++) {
            Core.line(drawMat, new Point(0, i * rows / GRID_SIZE), new Point(cols, i * rows / GRID_SIZE), new Scalar(0, 255, 0, 255), 3);
            Core.line(drawMat, new Point(i * cols / GRID_SIZE, 0), new Point(i * cols / GRID_SIZE, rows), new Scalar(0, 255, 0, 255), 3);
        }
    }

從google 查的文件

line( img,
        start,
        end,
        Scalar( 0, 0, 0 ),
        thickness,
        lineType );

  drawMat  -> img  data
   new Point(0, i * rows / GRID_SIZE)  ->  start point
   new Point(cols, i * rows / GRID_SIZE) -> end point
   new Scalar(0, 255, 0, 255) ->   color
   3  ->  thickness


==================================================================


mPuzzle15.prepareNewGame();   會呼叫



public synchronized void prepareNewGame() {
        do {
            shuffle(mIndexes);
        } while (!isPuzzleSolvable());
    }


//   利用一個迴圈...把取到的亂數所指到的位置.....  進行 swap...
private static void shuffle(int[] array) {
        for (int i = array.length; i > 1; i--) {
            int temp = array[i - 1];
            int randIx = (int) (Math.random() * i);
            array[i - 1] = array[randIx];
            array[randIx] = temp;
        }
    }


//  主程式
public synchronized Mat puzzleFrame(Mat inputPicture) {
        Mat[] cells = new Mat[GRID_AREA];
        int rows = inputPicture.rows();
        int cols = inputPicture.cols();

        rows = rows - rows%4;
        cols = cols - cols%4;

        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                int k = i * GRID_SIZE + j;
                cells[k] = inputPicture.submat(i * inputPicture.rows() / GRID_SIZE, (i + 1) * inputPicture.rows() / GRID_SIZE, j * inputPicture.cols()/ GRID_SIZE, (j + 1) * inputPicture.cols() / GRID_SIZE);
            }
        }

        rows = rows - rows%4;
        cols = cols - cols%4;

        // copy shuffled tiles
        for (int i = 0; i < GRID_AREA; i++) {
            int idx = mIndexes[i];
            if (idx == GRID_EMPTY_INDEX)
                mCells15[i].setTo(GRID_EMPTY_COLOR);
            else {
                cells[idx].copyTo(mCells15[i]);
                if (mShowTileNumbers) {
                    Core.putText(mCells15[i], Integer.toString(1 + idx), new Point((cols / GRID_SIZE - mTextWidths[idx]) / 2,
                            (rows / GRID_SIZE + mTextHeights[idx]) / 2), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, new Scalar(255, 0, 0, 255), 2);
                }
            }
        }

        for (int i = 0; i < GRID_AREA; i++)
            cells[i].release();

        drawGrid(cols, rows, mRgba15);

        return mRgba15;
    }









沒有留言:

張貼留言