Cv::Mat
Properties
-
Mat::channels()
: 채널 수를 반환한다. -
Mat::elemSize()
: Element 개수를 반환한다. 1개 속성당 갖고 있는 엘리먼트를 가리킨다. 채널수와 비슷하지만 구하는 방법 자체가 다르다. (추가 갱신 필요) -
Mat::cols
: column 개수를 반환한다. 너비(Width)와 동일하다. -
Mat::rows
: row 개수를 반환한다. 높이(Height)와 동일하다. -
Mat::dims
: 차원 수(dimensionality). -
Mat::data
: 실제 데이터가 존재하는uint8_t
의 동적 메모리 Pointer. -
Mat::total()
: 차원 수(dimensionality)를 포함하는 전체 크기를 반환한다. 이 값은 데이터(Mat::data
)크기와 다르다. -
Mat::total() * Mat::elemSize()
: 전체 데이터(Mat::data
) 크기.
How to create
uint8_t
의 데이터 단위를 갖고 있으며, 세 개의 채널을 사용하는 매트릭스를 생성하고 싶다면 아래와 같이 사용하면 된다.
Load and Display an Image
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
Data loop
for (int y = 0; y < mask.rows; ++y) {
for (int x = 0; x < mask.cols; ++x) {
cout << std::hex << *(mask.data + (y * mask.step) + x);
}
}
Draw Text
void drawButton(cv::Mat & output, std::string const & title, int x, int y, int width, int height)
{
assert(output.empty() == false);
int const PADDING = 3;
int const FONT_FACE = cv::FONT_HERSHEY_PLAIN;
double const FONT_SCALE = 1.5;
int const THICKNESS = 2;
cv::Scalar const BACKGROUND = cv::Scalar( 94, 73, 52); // COLOR NAME: WET ASPHALT - RGB(52,73,94)
cv::Scalar const FOREGROUND = cv::Scalar(255, 255, 255);
int base_line;
cv::Size const TEXT_SIZE = cv::getTextSize(title, FONT_FACE, FONT_SCALE, THICKNESS, &base_line);
cv::Rect const IMAGE_RECT = cv::Rect(x + PADDING, y + PADDING, width - PADDING, height - PADDING);
// 중앙정렬을 위한 TEXT 위치 계산.
cv::Point const TEXT_POINT = cv::Point(
IMAGE_RECT.x + (IMAGE_RECT.width / 2) - (TEXT_SIZE.width / 2)
, IMAGE_RECT.y + (IMAGE_RECT.height / 2) - (TEXT_SIZE.height / 2) + (base_line * 2));
cv::rectangle(output, IMAGE_RECT, BACKGROUND, cv::FILLED);
cv::putText(output, title, TEXT_POINT, FONT_FACE, FONT_SCALE, FOREGROUND, THICKNESS, cv::LINE_AA);
}
바로 사용할 수 있는 함수는 아래와 같다.
void drawText(cv::InputOutputArray image, std::string const & text, int right, int top, int r, int g, int b)
{
int const FONT = cv::FONT_HERSHEY_SIMPLEX;
int const THICKNESS = 1;
double const SCALE = 1.0;
cv::Point const POINT(0, 0);
cv::Scalar const COLOR(255, 0, 0);
int base_line;
cv::Size const TEXT_SIZE = cv::getTextSize(text, FONT, SCALE, THICKNESS, &base_line);
cv::Point const DRAW_POINT(POINT.x/*+ TEXT_SIZE.width*/, POINT.y + TEXT_SIZE.height + base_line);
cv::putText(image, text, DRAW_POINT, FONT, SCALE, COLOR, THICKNESS);
}
copyTo vs clone
clone은 새로운 Mat을 선언. 즉, 메모리를 추가로 할당한다.
Fill color
Binary buffer to Mat
bool updateMat(cv::Mat & mat, uint8_t const * data, int width, int height, int channel)
{
assert(data != nullptr);
assert(width > 0);
assert(height > 0);
assert(channel == 1 || channel == 3);
if (/* * */mat.channels() != channel
|| mat.cols != width
|| mat.rows != height) {
int type = (channel == 3 ? CV_8UC3 : CV_8UC1);
mat.create(height, width, type);
}
memcpy(mat.data, data, mat.total() * mat.elemSize());
return true;
}