- main方法定义
int main(int argc, char **argv) {
Mat mat = imread("图像路径");
if (mat.empty()){
cout << "加载错误" << endl;}
else{
cout << "加载正常" << endl;}
namedWindow("原图像",WINDOW_NORMAL);
imshow("原图像", mat);
colordemo(mat);
waitKey(0);
destroyAllWindows();
return 0;
- 定义图像并保存图片
void colordemo(Mat &image) {
Mat gray, hsv;
cvtColor(image, hsv, COLOR_BGR2HSV);
cvtColor(image, gray, COLOR_BGR2GRAY);
imshow("HSV", hsv);
imshow("灰度", gray);
imwrite("保存路径/hsv.png", hsv);
imwrite("保存路径/gray.png", gray);
}
- Mat函数浅解与图像克隆、复制
void mat_create(Mat &image) {
Mat mat1,mat2;
mat1 = image.clone();
image.copyTo(mat2);
namedWindow("克隆", WINDOW_FREERATIO);
namedWindow("复制", WINDOW_FREERATIO);
imshow("克隆",mat1);
imshow("复制", mat2);
Mat mat3 = Mat::zeros(Size(8, 8), CV_8UC3);
mat3 = Scalar(255,0,0);
mat3.cols;
mat3.rows;
mat3.channels();
std::cout<< mat3 <<endl;
namedWindow("空白图像", WINDOW_FREERATIO);
imshow("空白图像", mat3);
- 图像像素值遍历
void xiangsu1(Mat &image) {
int w = image.cols;
int h = image.rows;
int dims = image.channels();
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
if (dims == 1) {
int pv = image.at<uchar>(row, col);
image.at<uchar>(row, col) = 255 - pv;
}
if (dims == 3) {
Vec3b bgr = image.at<Vec3b>(row, col);
image.at<Vec3b>(row, col)[0] = 255 - bgr[0];
image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
image.at<Vec3b>(row, col)[2] = 255 - bgr[2];
}
}
}
namedWindow("像素读写演示", WINDOW_FREERATIO);
imshow("像素读写演示", image);
}
- 对图像像素进行加减乘除操作
void xiangsu2(Mat &image) {
Mat mat4,mat5,mat6,mat7;
Mat m = Mat::zeros(image.size(), image.type());
Mat n = Mat::zeros(image.size(), image.type());
m = Scalar(2, 2, 2);
n = Scalar(50, 50, 50);
add(image, n, mat4);
subtract(image, n, mat5);
multiply(image, m, mat6);
divide(image,m,mat7);
namedWindow("加法操作", WINDOW_FREERATIO);
imshow("加法操作", mat4);
namedWindow("减法操作", WINDOW_FREERATIO);
imshow("减法操作", mat5);
namedWindow("乘法操作", WINDOW_FREERATIO);
imshow("乘法操作", mat6);
namedWindow("除法操作", WINDOW_FREERATIO);
imshow("除法操作", mat7);
}
- 图像滚动条定义
Mat m, dst, src;
int lightess = 50;
static void on_lightness(int b, void* userdata) {
Mat image = *((Mat*)userdata);
m = Mat::zeros(image.size(), image.type());
dst = Mat::zeros(image.size(), image.type());
addWeighted(image, 1.0, m, 0, b, dst);
imshow("亮度和饱和度调整", dst);
}
static void on_contrast(int b, void* userdata) {
Mat image = *((Mat*)userdata);
m = Mat::zeros(image.size(), image.type());
dst = Mat::zeros(image.size(), image.type());
double contrast = b / 100.0;
addWeighted(image, contrast, m, 0.0, 0, dst);
imshow("亮度和饱和度调整", dst);
}
void gundong(Mat &image) {
namedWindow("亮度和饱和度调整",WINDOW_NORMAL);
int lightness = 50;
int contrast_value = 100;
int max_value = 100;
createTrackbar("亮度:", "亮度和饱和度调整", &lightess, max_value,on_lightness, (void*)(&image));
createTrackbar("饱和度:", "亮度和饱和度调整", &contrast_value, 200, on_contrast,(void*)(&image));
on_lightness(50, &image);
}
- 接收键盘信号操作
void key_value(Mat &image) {
Mat dst = Mat::zeros(image.size(), image.type());
while (true)
{
int c = waitKey(100);
if (c == 27) {
break;
}
if (c == 49) {
cout << "you enter key # 1" << endl;
cvtColor(image, dst, COLOR_BGR2GRAY);
}
if (c == 50) {
cout << "you enter key # 2" << endl;
cvtColor(image, dst, COLOR_BGR2HSV);
}
if (c == 51) {
cout << "you enter key # 3" << endl;
dst = Scalar(100, 100, 100);
add(image, dst, dst);
}
namedWindow("键盘响应", WINDOW_NORMAL);
imshow("键盘响应",dst);
}
}
- 图像16种伪色彩转化轮播
void color_style(Mat &image) {
int dex = 1;
Mat dst = Mat::zeros(image.size(), image.type());
int colormap[] = {
COLORMAP_AUTUMN,COLORMAP_BONE,COLORMAP_JET,COLORMAP_WINTER,
COLORMAP_RAINBOW,COLORMAP_OCEAN,COLORMAP_SUMMER,COLORMAP_SPRING,
COLORMAP_COOL,COLORMAP_PINK,COLORMAP_HOT,COLORMAP_PARULA,
COLORMAP_VIRIDIS,COLORMAP_CIVIDIS,COLORMAP_TWILIGHT,COLORMAP_TWILIGHT_SHIFTED};
while (true){
int c = waitKey(1500);
if (c == 27) {
break;
}
if (c == 49) {
applyColorMap(image, dst, colormap[dex % 16]);
dex++;
}
namedWindow("图像轮播", WINDOW_NORMAL);
imshow("图像轮播", dst);
}
}
- 图像矩阵绘制与图像逻辑操作
void bitwise_demo(Mat &image) {
Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);
rectangle(m1, Rect(100, 100, 80, 80), Scalar(255, 255, 0), -1, LINE_8, 0);
rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);
Mat std1,std2,std3,std4;
bitwise_and(m1,m2,std1);
bitwise_not(m1, std2);
bitwise_xor(m1, m2, std3);
bitwise_or(m1, m2, std4);
imshow("取交集", std1);
imshow("取反", std2);
imshow("异或集", std3);
imshow("或集", std4);
}
- 三基色通道分离
void channels_demo(Mat &image) {
vector<Mat>mv;
split(image, mv);
Mat dst;
mv[1] = 0;
mv[2] = 0;
merge(mv, dst);
int from_to[] = { 0,2,1,1,2,0 };
mixChannels(&image, 1, &dst, 1, from_to, 3);
imshow("通道颜色转换", dst);
}
- 色彩转换提取轮廓(红绿互换)
void inrange_demo(Mat &image) {
Mat hsv,mask;
cvtColor(image, hsv, COLOR_BGR2HSV);
inRange(hsv, Scalar(35,43,46), Scalar(77 , 255, 255), mask);
Mat redback = Mat::zeros(image.size(), image.type());
redback = Scalar(40, 40, 200);
bitwise_not(mask, mask);
imshow("mask", mask);
image.copyTo(redback, mask);
imshow("roi区域提取", redback);
}
- 图像最大最小值和方差等特征提取
void mean_demo(Mat &image) {
double minv, maxv;
Point minLoc, maxLoc;
vector<Mat>mv;
split(image, mv);
for (int i = 0; i < mv.size(); i++) {
minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat());
cout << "No.channels:" << i << ";min value:" << minv << ";max value:" << maxv << endl;
}
Mat mean, stddev;
meanStdDev(image, mean, stddev);
cout << "means:" << mean << endl;
cout << "stddev:" << stddev<<endl;
}
- 绘制矩形、圆、直线
void drawing_demo(Mat &image) {
Rect rect;
rect.x = 200;
rect.y = 200;
rect.width = 100;
rect.height = 100;
rectangle(image, rect, Scalar(0, 0, 255), 1, 8, 0);
circle(image, Point(350, 400), 40, Scalar(255, 0, 0), 1, 8, 0);
line(image, Point(100, 100), Point(350, 400), Scalar(0, 255, 0), 4, LINE_AA, 0);
namedWindow("绘制演示", WINDOW_FREERATIO);
imshow("绘制演示", image);
}
- 随机线条绘制
void random_drawing() {
Mat canvas = Mat::zeros(Size(512,512),CV_8UC3);
RNG rng(12345);
int w = canvas.cols;
int h = canvas.rows;
while (true){
int c = waitKey(1000);
if (c == 27) {
break;
}
int x1 = rng.uniform(0, w);
int y1 = rng.uniform(0, h);
int x2 = rng.uniform(0, w);
int y2 = rng.uniform(0, h);
int b = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int r = rng.uniform(0, 255);
canvas = Scalar(0,0,0);
line(canvas, Point(x1, y1), Point(x2, y2), Scalar(b, g, r), 1, LINE_AA, 0);
imshow("绘制", canvas);
}
}
- 多边形的填充与绘制
void duobian_demo() {
Mat canvas = Mat::zeros(Size(512, 512), CV_8UC3);
Point p1(100, 100);
Point p2(350, 100);
Point p3(450, 280);
Point p4(320, 450);
Point p5(80, 100);
std::vector<Point>pst;
pst.push_back(p1);
pst.push_back(p2);
pst.push_back(p3);
pst.push_back(p4);
pst.push_back(p5);
std::vector<std::vector<Point>>contours;
contours.push_back(pst);
drawContours(canvas, contours, -1, Scalar(255, 0, 0), 2);
imshow("多边形绘制", canvas);
}
- 鼠标事件绑定(图像区域截取并显示)
Point sp(-1, -1);
Point ep(-1, -1);
Mat temp;
void mouse_draw(int event, int x, int y, int flags, void *userdata) {
Mat image = *((Mat*)userdata);
if (event == EVENT_LBUTTONDOWN) {
sp.x = x;
sp.y = y;
cout << "坐标:" << sp << endl;
}
else if (event == EVENT_LBUTTONUP) {
ep.x = x;
ep.y = y;
int dx = ep.x - sp.x;
int dy = ep.y - sp.y;
if (dx > 0 && dy > 0) {
Rect box(sp.x, sp.y, dx, dy);
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
imshow("鼠标绘制", image);
imshow("ROI区域", image(box));
sp.x = -1;
sp.y = -1;
}
}
else if (event == EVENT_MOUSEMOVE) {
if (sp.x > 0 && sp.y > 0) {
ep.x = x;
ep.y = y;
int dx = ep.x - sp.x;
int dy = ep.y - sp.y;
if (dx > 0 && dy > 0) {
Rect box(sp.x, sp.y, dx, dy);
temp.copyTo(image);
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
imshow("鼠标绘制", image);
}
}
}
}
void mouse(Mat &image) {
namedWindow("鼠标绘制", WINDOW_FREERATIO);
setMouseCallback("鼠标绘制", mouse_draw, (void*)(&image));
imshow("鼠标绘制", image);
temp = image.clone();
}