创建Mat
// 5行3列随机值
Mat img = Mat(5, 3, CV_8UC3);
randu(img, Scalar::all(0), Scalar::all(255));
// 2行2列固定值
Mat img1(Size(2, 2), CV_8UC3, Scalar(0, 0, 255));
// create()函数
Mat img2;
img2.create(Size(4, 4), CV_8UC3);
输出Mat
cout << img << endl;
cout << format(img, Formatter::FMT_PYTHON) << endl;
cout << format(img, Formatter::FMT_NUMPY) << endl;
获取行数和列数
行数: src.rows
列数: src.cols
形态学
// 创建核
Mat kernal = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat img_dilate, img_erosion;
// 膨胀
dilate(gray, img_dilate, kernal);
// 腐蚀
erode(img_dilate, img_erosion, kernal);
// 开闭运算 礼帽 黑帽
morphologyEx(gray, dst_open, MORPH_TOPHAT, kernal);
MORPH_OPEN: 先腐蚀后膨胀
MORPH_CLOSE: 先膨胀后腐蚀
MORPH_TOPHAT: 原图与开运算之差
MORPH_BLACKHAT: 闭运算与原图之差
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int artc, char** argv) {
Mat img = Mat(5, 3, CV_8UC3);
randu(img, Scalar::all(0), Scalar::all(255));
cout << img << endl;
// [ 91, 2, 79, 179, 52, 205, 236, 8, 181;
// 239, 26, 248, 207, 218, 45, 183, 158, 101;
// 102, 18, 118, 68, 210, 139, 198, 207, 211;
// 181, 162, 197, 191, 196, 40, 7, 243, 230;
// 45, 6, 48, 173, 242, 125, 175, 90, 63]
cout << "python:" << endl;
cout << format(img, Formatter::FMT_PYTHON) << endl;
// python:
// [[[ 91, 2, 79], [179, 52, 205], [236, 8, 181]],
// [[239, 26, 248], [207, 218, 45], [183, 158, 101]],
// [[102, 18, 118], [ 68, 210, 139], [198, 207, 211]],
// [[181, 162, 197], [191, 196, 40], [ 7, 243, 230]],
// [[ 45, 6, 48], [173, 242, 125], [175, 90, 63]]]
cout << "numpy:" << endl;
cout << format(img, Formatter::FMT_NUMPY) << endl;
// numpy:
// array([[[ 91, 2, 79], [179, 52, 205], [236, 8, 181]],
// [[239, 26, 248], [207, 218, 45], [183, 158, 101]],
// [[102, 18, 118], [ 68, 210, 139], [198, 207, 211]],
// [[181, 162, 197], [191, 196, 40], [ 7, 243, 230]],
// [[ 45, 6, 48], [173, 242, 125], [175, 90, 63]]], dtype='uint8')
Mat img1(Size(2, 2), CV_8UC3, Scalar(0, 0, 255));
cout << format(img1, Formatter::FMT_PYTHON) << endl;
// [[[ 0, 0, 255], [ 0, 0, 255]],
// [[ 0, 0, 255], [ 0, 0, 255]]]
Mat img2;
img2.create(Size(4, 4), CV_8UC3);
cout << format(img2, Formatter::FMT_PYTHON) << endl;
// [[[ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0]],
// [[ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0]],
// [[ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0]],
// [[ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0]]]
Mat src = imread("/homevin/Picturesadow.png", IMREAD_COLOR);
if (src.empty()) {
cout << "can't find picture" << endl;
return -1;
}
cout << src.rows << endl;
cout << src.cols << endl;
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
Mat kernal = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat img_dilate, img_erosion;
//Mat dst_open, dst_theshould;
// erode(gray, dst, kernal);
dilate(gray, img_dilate, kernal);
erode(img_dilate, img_erosion, kernal);
Mat img_diff = img_erosion - gray;
img_diff = 255 - img_diff;
Mat img_norm;
normalize(img_diff, img_norm, 0, 255, NORM_MINMAX);
//morphologyEx(gray, dst_open, MORPH_TOPHAT, kernal);
//threshold(dst_open, dst_theshould, 110, 255, THRESH_BINARY);
// namedWindow("src");
// imshow("src", img_diff);
waitKey(0);
return 0;
}
原图
去阴影
Trackbar找阈值
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
string winName = "threshould";
Mat src, gray;
int g_ThreshouldValue = 100;
// 回调函数
void on_Threshould(int ,void* )
{
threshold(gray, dst, g_ThreshouldValue, 255, THRESH_BINARY);
imshow(winName, dst);
}
int main(int artc, char** argv) {
src = imread("/home/kavin/Pictures/panels/panels_2/dst_1.png", IMREAD_COLOR);
Mat dst = src.clone();
if (src.empty()) {
cout << "can't find picture" << endl;
return -1;
}
Mat blur;
GaussianBlur(src, blur, Size(3, 3), 0, 0);
cvtColor(blur, gray, COLOR_BGR2GRAY);
namedWindow(winName, WINDOW_NORMAL);
//创建trackbar,确定二值化的阈值
createTrackbar("threshould", winName, &g_ThreshouldValue, 255, on_Threshould);
on_Threshould(0, 0);
while (1)
{
int key;
key = waitKey(20);
if (char(key) == 27) break;
}
// threshold(gray, dst, 135, 255, THRESH_BINARY);
waitKey(0);
return 0;
}
提取矩形
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
string winName = "threshould";
Mat src, gray;
int main(int artc, char** argv) {
src = imread("/home/kavin/Pictures/panels/panels_2/dst_1.png", IMREAD_COLOR);
Mat dst = src.clone();
if (src.empty()) {
cout << "can't find picture" << endl;
return -1;
}
Mat blur;
GaussianBlur(src, blur, Size(3, 3), 0, 0);
cvtColor(blur, gray, COLOR_BGR2GRAY);
namedWindow(winName, WINDOW_NORMAL);
gray = gray > 130;
Mat kernal = getStructuringElement(MORPH_RECT, Size(12, 12));
Mat img_dilate, img_erosion;
Mat dstImage = Mat::zeros(src.size(), CV_8U);
dilate(gray, img_dilate, kernal);
// imshow("dilate", img_dilate);
vector<vector<Point> > contours; // 存储轮廓点
vector<Vec4i> hierarchy;
findContours(img_dilate, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
vector<Rect> panelsRect;
// drawContours(src, contours, -1, Scalar(255, 0, 255), 3);
// 画出符合条件的轮廓,并生成矩形
for (int i = 0; i < contours.size(); i++) {
if (arcLength(contours[i], true) >= 450 && arcLength(contours[i], true) <= 500) {
drawContours(src, contours, i, Scalar(255, 0, 255), 2);
Rect boundRect = boundingRect(Mat(contours[i]));
rectangle(src, boundRect.tl(), boundRect.br(), Scalar(0, 255, 0), 2);
panelsRect.push_back(boundRect);
}
}
cout << panelsRect.size() << endl;
Mat panel;
for (int i = 0; i < 2; i++) {
dst(panelsRect[i]).copyTo(panel);
imshow("panel_" + to_string(i), panel);
}
imshow(winName, src);
waitKey(0);
return 0;
}
原图