12/08/2018, 10:09

using openCv part 2

1. Làm thế nào để thu được hình ảnh camera sử dụng OpenCV Trong ví dụ đầu tiên này, chúng tôi sẽ dựa vào các khung xem trước từ các máy ảnh từ khi chúng tôi có thể lấy lại những hình ảnh tương đối nhanh. Chúng tôi cần phải chọn một kích thước thích hợp cho các khung xem trước, như khung quá nhỏ ...

1. Làm thế nào để thu được hình ảnh camera sử dụng OpenCV

Trong ví dụ đầu tiên này, chúng tôi sẽ dựa vào các khung xem trước từ các máy ảnh từ khi chúng tôi có thể lấy lại những hình ảnh tương đối nhanh. Chúng tôi cần phải chọn một kích thước thích hợp cho các khung xem trước, như khung quá nhỏ sẽ dẫn đến một kết quả xấu khi chúng ta làm việc xử lý, và khung hình quá lớn sẽ làm chậm tất cả mọi thứ đến một mức độ không thể chấp nhận. Kể từ khi máy ảnh điện thoại thông minh thường có một bộ khác nhau của kích thước được hỗ trợ cho các khung xem trước, chúng ta cần phải chọn một kích thước tối thiểu chấp nhận và đi qua tất cả để tìm ra điều đúng. OpenCV có API Java của riêng mình, và không dựa trên dựa trên Java Máy ảnh API Android. Các mã sau mở máy ảnh và thiết lập kích thước xem trước mức chấp nhận được.

private void setupCamera() {
if (mCamera != null) {
   VideoCapture camera = mCamera;
   mCamera = null; // Make it null before releasing...
  camera.release();
}

mCamera = new VideoCapture(mCameraId);

List<Size> previewSizes = mCamera.getSupportedPreviewSizes();
double smallestPreviewSize = 1280 * 720; // We should be smaller than this...
double smallestWidth = 480; // Let's not get smaller than this...
for (Size previewSize : previewSizes) {
    if (previewSize.area() < smallestPreviewSize && previewSize.awidth >= smallestWidth) {
        mPreviewSize = previewSize;
    }
}

mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mPreviewSize.awidth);
mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mPreviewSize.height);
}

Một điều quan trọng cần nhớ khi làm việc với OpenCV là chúng ta cần rất nhiều RAM cho những hình ảnh chúng tôi đang xử lý. OpenCV sử dụng ma trận để đại diện cho tất cả các hình ảnh như vậy để được như hiệu quả nhất có thể, chúng tôi sẽ phân bổ các ma trận cần một lần và tái sử dụng chúng cho mỗi khung hình. Một khi chúng ta có các thiết lập máy ảnh và các ma trận phân bổ, chúng ta có thể bắt đầu để lấy khung preview để xử lý. Các mã sau đây cho thấy cách chúng ta làm điều này với OpenCV.

while (mDoProcess && mCamera != null) {
boolean grabbed = mCamera.grab();
if (grabbed) {
    mCamera.retrieve(mCurrentFrame,
Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);
    // Process mCurrentFrame…
}
}

2. Làm thế nào để xử lý một khung camera

Bây giờ chúng ta có một khung xem trước trong mCurrentFrame rằng chúng ta có thể sử dụng để chế biến. Trong trường hợp này, chúng ta sẽ sử dụng chức năng inRange để tạo ra một mặt nạ mà chỉ bao gồm một khoảng màu cụ thể. Để có kết quả tốt nhất, đầu tiên chúng ta sẽ chuyển đổi các khung nắm lấy để HSV-format. Khi chúng tôi có mặt nạ, chúng tôi rút ra những khung ban đầu vào một ma trận mới bằng cách sử dụng mặt nạ, chúng tôi nhận được từ các inRange chức năng. Các mã sau đây cho thấy làm thế nào để chuyển đổi định dạng từ RGB sang HSV, tạo mặt nạ màu và vẽ kết quả.

// Convert mCurrentFrame to HSV format and store
the result in mCurrentFrameHsv
Imgproc.cvtColor(mCurrentFrame, mCurrentFrameHsv,
Imgproc.COLOR_RGB2HSV);
// Generate the color mask based on the lower and upper
color limits
Core.inRange(mCurrentFrameHsv, mLowerColorLimit,
mUpperColorLimit, mInRangeResult);
// Clear the final image before we copy the new filtered image
mFilteredFrame.setTo(new Scalar(0, 0, 0));
// Copy the original frame using the color mask
mCurrentFrame.copyTo(mFilteredFrame, mInRangeResult);

OpenCV_screenshot2.png

Màn bắn thấy khung máy ảnh xử lý khi một màu sắc đã được chọn. Như bạn có thể thấy, chỉ có khoảng màu đỏ được hiển thị.

3. Làm thế nào để hiển thị các kết quả của hình ảnh được xử lý

kết quả Bitmap bây giờ có thể được sử dụng để vẽ một SurfaceView hoặc tương tự để hiển thị kết quả. Cách dễ nhất để làm điều này là để chuyển đổi ma trận OpenCV đến một đối tượng Bitmap Android. Có một lớp học Util cung cấp một chức năng cho việc này.

// Convert the matrix to an Android bitmap
Utils.matToBitmap(result, resultBitmap, true);

Từ thời điểm này, bạn chỉ có thể rút ra những Bitmap như bình thường trên một SurfaceView, hoặc gán nó vào một ImageView.

0