一:显示图像并保存
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("D:/images/011.jpg",IMREAD_GRAYSCALE);
if (src.empty())
{
printf("could not load image");
}
namedWindow("输入窗口", WINDOW_FREERATIO);
imshow("输入窗口", src);
waitKey(0);
imwrite("E:\\QTFiles\\zhh1913021023\\example1_zhh\\test1.png",src);
destroyAllWindows();
return 0;
}
二:色彩转换函数:cvtcolor
#include
#include
using namespace std;
using namespace cv;
class QuickDemo
{
public:
void colorSpace_Demo(Mat &imge);
};
void QuickDemo::colorSpace_Demo(Mat &image)
{
Mat gray, hsv;
cvtColor(image,hsv,COLOR_BGR2HSV);
cvtColor(image,gray,COLOR_BGR2GRAY);
imshow("HSV",hsv);
imshow("灰度",gray);
imwrite("D:/hsv.jpg",hsv);
imwrite("D:/gray.jpg",gray);
}
int main()
{
Mat src = imread("D:/images/1.jpg",IMREAD_ANYCOLOR);
if (src.empty())
{
printf("could not load image");
return -1;
}
namedWindow("输入窗口", WINDOW_FREERATIO);
imshow("输入窗口", src);
QuickDemo qd;
qd.colorSpace_Demo(src);
waitKey(0);
destroyAllWindows();
return 0;
}
三:mat对象
通过创建新的Mat对象来创建用户的特定的底色画布,创建图像的基本类型有两种一种是ones一种是zeros,ones()中的第一个参数代表图像的大小,第二个参数代表创建几维的图像,UC代表无符号字符型,数组3代表通道数。克隆和赋值的区别,克隆就是产生一个新的对象,新对象改变属性,旧对象属性不变(各自为政)。赋值是二者同体,当新属性发生改变,旧属性也发生改变(二者同体)。
void QuickDemo::mat_creation_demo(Mat &image)
{
Mat m1, m2;
m1 = image.clone();
image.copyTo(m2);
Mat m3 = Mat::ones(Size(400, 400), CV_8UC3);
m3 = Scalar(255, 0, 0);
Mat m4 = m3.clone();
m4 = Scalar(0, 255, 255);
imshow("图像3", m3);
imshow("图像4", m4);
}
mat对象的7种创建方式,分别创建灰度和彩色图像
Mat image1(10,10,CV_8UC1,Scalar(0,255,255));
Mat image1_rgb(10,10,CV_8UC3,Scalar(0,255,255));
int sz[3]={10,10,10};
Mat image2(2,sz,CV_8UC3,Scalar::all(0));
Mat image2_rgb(2,sz,CV_8UC1,Scalar::all(0));
IplImage *img = cvLoadImage("d:/image/melina.jpg",CV_8UC1);
IplImage *img1 = cvLoadImage("d:/image/melina.jpg",CV_8UC3);
Mat image3=cvarrToMat(img);
Mat image3_rgb=cvarrToMat(img1);
Mat image4,image4_rgb;
image4.create(10,10,CV_8UC1);
image4_rgb.create(10,10,CV_8UC3);
Mat image5 = Mat::eye(10, 10,CV_8UC1);
Mat image5_rgb=Mat::eye(10, 10,CV_8UC3);
Mat image6=(Mat_<unsigned char>(3,3)<<1,2,3,4,5,6,7,8,9,CV_8UC1);
Mat image6_rgb=(Mat_<unsigned char>(3,3)<<1,2,3,4,5,6,7,8,9,CV_8UC3);
Mat image1_row=image1.row(1).clone();
Mat image1_row_rgb;
image1_rgb.copyTo(image1_row_rgb);
四:图像像素读写
数组方式
void QuickDemo::pixel_visit_demo(Mat &image)
{
int dims = image.channels();
int h = image.rows;
int w = image.cols;
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 QuickDemo::pixel_visit_demo(Mat &image)
{
int dims = image.channels();
int h = image.rows;
int w = image.cols;
for (int row = 0; row < h; row++)
{
uchar *current_row = image.ptr<uchar>(row);
for (int col = 0; col < w; col++)
{
if (dims == 1)
{
int pv = *current_row;
*current_row++ = 255 - pv;
}
if (dims == 3)
{
*current_row++ = 255 - *current_row;
*current_row++ = 255 - *current_row;
*current_row++ = 255 - *current_row;
}
}
}
namedWindow("像素读写演示", WINDOW_FREERATIO);
imshow("像素读写演示", image);
}
五:图像像素操作:加减乘除
void QuickDemo::operators_demo(Mat &image)
{
Mat dst = Mat::zeros(image.size(), image.type());
Mat m = Mat::zeros(image.size(), image.type());
dst = image - Scalar(50, 50, 50);
m = Scalar(50, 50, 50);
multiply(image,m,dst);
imshow("乘法操作", dst);
add(image, m, dst);
imshow("加法操作", dst);
subtract(image, m, dst);
imshow("减法操作", dst);
divide(image, m, dst);
namedWindow("加法操作", WINDOW_FREERATIO);
imshow("加法操作", dst);
int dims = image.channels();
int h = image.rows;
int w = image.cols;
for (int row = 0; row < h; row++)
{
for (int col = 0; col < w; col++)
{
Vec3b p1 = image.at<Vec3b>(row, col);
Vec3b p2 = m.at<Vec3b>(row, col);
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0] + p2[0]);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1] + p2[1]);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);
}
}
imshow("加法操作", dst);
}
六:滚动条调节图片亮度
Mat src, dst, m;
int lightness = 50;
static void on_track(int ,void*)
{
m = Scalar(lightness,lightness,lightness);
subtract(src, m, dst);
imshow("亮度调整", dst);
}
void QuickDemo::tracking_bar_demo(Mat &image)
{
namedWindow("亮度调整",WINDOW_AUTOSIZE);
dst = Mat::zeros(image.size(), image.type());
m = Mat::zeros(image.size(), image.type());
src = image;
int max_value = 100;
createTrackbar("Value Bar:", "亮度调整", &lightness, max_value,on_track);
on_track(50, 0);
}
可传参数
static void on_lightness(int b ,void* userdata)
{
Mat image = *((Mat*)userdata);
Mat dst = Mat::zeros(image.size(), image.type());
Mat m = Mat::zeros(image.size(), image.type());
m = Scalar(b,b,b);
addWeighted(image,1.0,m,0,b,dst);
imshow("亮度&对比度调整", dst);
}
static void on_contrast(int b, void* userdata)
{
Mat image = *((Mat*)userdata);
Mat dst = Mat::zeros(image.size(), image.type());
Mat m = Mat::zeros(image.size(), image.type());
double contrast = b / 100.0;
addWeighted(image, contrast, m, 0.0, 0, dst);
imshow("亮度&对比度调整", dst);
}
void QuickDemo::tracking_bar_demo(Mat &image)
{
namedWindow("亮度&对比度调整",WINDOW_AUTOSIZE);
int lightness = 50;
int max_value = 100;
int contrast_value = 100;
createTrackbar("Value Bar:", "亮度&对比度调整", &lightness, max_value, on_lightness,(void*)(&image));
createTrackbar("Contrast Bar:", "亮度&对比度调整", &contrast_value, 200, on_contrast, (void*)(&image));
on_lightness(50, &image);
}
七:键盘响应
void QuickDemo::key_demo(Mat &image)
{
Mat dst= Mat::zeros(image.size(), image.type());
while (true)
{
char c = waitKey(100);
if (c == 27) {
break;
}
if (c == 49)
{
std::cout <<"you enter key #1" << std::endl;
cvtColor(image, dst, COLOR_BGR2GRAY);
}
if (c == 50)
{
std::cout << "you enter key #2" << std::endl;
cvtColor(image, dst, COLOR_BGR2HSV);
}
if (c == 51)
{
std::cout << "you enter key #3" << std::endl;
dst = Scalar(50, 50, 50);
add(image,dst,dst);
}
imshow("键盘响应",dst);
std::cout << c << std::endl;
}
}
八:调用OpenCV自带颜色
void QuickDemo::color_style_demo(Mat &image)
{
int colormap[] = {
COLORMAP_AUTUMN ,
COLORMAP_BONE,
COLORMAP_CIVIDIS,
COLORMAP_DEEPGREEN,
COLORMAP_HOT,
COLORMAP_HSV,
COLORMAP_INFERNO,
COLORMAP_JET,
COLORMAP_MAGMA,
COLORMAP_OCEAN,
COLORMAP_PINK,
COLORMAP_PARULA,
COLORMAP_RAINBOW,
COLORMAP_SPRING,
COLORMAP_TWILIGHT,
COLORMAP_TURBO,
COLORMAP_TWILIGHT,
COLORMAP_VIRIDIS,
COLORMAP_TWILIGHT_SHIFTED,
COLORMAP_WINTER
};
Mat dst;
int index = 0;
while (true)
{
char c = waitKey(100);
if (c == 27) {
break;
}
if (c == 49)
{
std::cout << "you enter key #1" << std::endl;
imwrite("D:/gray.jpg", dst);
}
applyColorMap(image, dst, colormap[index%19]);
index++;
imshow("循环播放", dst);
}
}
九:图像像素的逻辑操作:与或非异或
void QuickDemo::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);
imshow("m1", m1);
imshow("m2", m2);
Mat dst;
bitwise_and(m1, m2, dst);
bitwise_or(m1, m2, dst);
bitwise_not(image, dst);
bitwise_xor(m1, m2, dst);
imshow("像素位操作", dst);
}
十:通道的分离和合并
void QuickDemo::channels_demo(Mat &image)
{
std::vector<Mat>mv;
split(image, mv);
Mat dst;
mv[0] = 0;
mv[2] = 0;
merge(mv, dst);
imshow("蓝色", dst);
int from_to[] = { 0,2,1,1,2,0 };
mixChannels(&image,1,&dst,1,from_to,3);
imshow("通道混合", dst);
}
十一:图像色彩空间转换
void QuickDemo::inrange_demo(Mat &image)
{
Mat hsv;
cvtColor(image, hsv, COLOR_BGR2HSV);
Mat mask;
inRange(hsv,Scalar(35,43,46),Scalar(77,255,255),mask);
imshow("mask",hsv);
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 QuickDemo::pixel_statistic_demo(Mat &image)
{
double minv, maxv;
Point minLoc, maxLoc;
std::vector<Mat>mv;
split(image, mv);
for (int i = 0; i < mv.size(); i++)
{
minMaxLoc(mv[i], &minv, &maxv, &minLoc, &maxLoc, Mat());
std::cout <<"No.channels:"<<i<<"minvalue:" << minv << "maxvalue:" << maxv << std::endl;
}
Mat mean, stddev;
meanStdDev(image, mean, stddev);
std::cout << "mean:" << mean << std::endl;
std::cout << "stddev:" << stddev << std::endl;
}
十三:图像几何形状的绘制及文字的写入
void drawing_demo(Mat &image)
{
Rect rect;
rect.x = 400;
rect.y = 200;
rect.width = 100;
rect.height = 100;
Mat bg = Mat::zeros(image.size(),image.type());
rectangle(bg, rect, Scalar(255, 0, 255), -1, 8, 0);
circle(bg, Point(350, 400), 15, Scalar(0, 0, 255), 2, LINE_AA, 0);
Mat dst;
RotatedRect rtt;
rtt.center = Point(200, 200);
rtt.size = Size(100, 200);
rtt.angle = 0.0;
line(bg,Point(100,100),Point(350,400), Scalar(0, 0, 255), 8, LINE_AA, 0);
ellipse(bg,rtt, Scalar(0, 0, 255), 2, 8);
putText(bg, "hello everyone", Point(bg.cols/2-200, bg.rows/2), CV_FONT_HERSHEY_COMPLEX, 1.0, Scalar(0, 255, 0), 8, LINE_8);
imshow("drawing",bg);
}
#include
#include
#include
using namespace std;
using namespace cv;
Mat src_bgImg;
const char *draw_window = "show windows";
void DrawLine();
void DrawRectangle();
void DrawEllipse();
void DrawCircle();
void DrawPolygon();
void DrawRandomLine();
int main()
{
src_bgImg = Mat::ones(500,500,CV_8UC3);
DrawLine();
DrawRectangle();
DrawEllipse();
DrawCircle();
DrawPolygon();
putText(src_bgImg,"zhenghonghui",Point(200,200),CV_FONT_HERSHEY_COMPLEX,1.0,Scalar(255,255,0),1,8);
namedWindow(draw_window,CV_WINDOW_AUTOSIZE);
imshow(draw_window,src_bgImg);
DrawRandomLine();
waitKey(0);
return 0;
}
void DrawLine()
{
Point p1 = Point(100, 50);
Point p2 = Point(300,300);
Scalar color = Scalar(0,255,255);
line(src_bgImg,p1,p2,color,3,LINE_8);
}
void DrawRectangle()
{
Rect rect = Rect(150,20,100,100);
Scalar color = Scalar(255, 0, 255);
rectangle(src_bgImg,rect,color,3,LINE_8);
}
void DrawEllipse()
{
Scalar color = Scalar(255, 0, 0);
ellipse(src_bgImg,Point(src_bgImg.cols/2,src_bgImg.rows/2),Size(src_bgImg.cols/4,src_bgImg.rows/8),90,0,360,color,2,LINE_8);
}
void DrawCircle()
{
Scalar color = Scalar(0, 255, 0);
Point center = Point(src_bgImg.cols/2,src_bgImg.rows/2);
circle(src_bgImg,center,80,color,2,LINE_8);
}
void DrawPolygon()
{
Scalar color = Scalar(255, 255, 0);
Point pts[1][5];
pts[0][0] = Point(100,100);
pts[0][1] = Point(100, 200);
pts[0][2] = Point(200, 200);
pts[0][3] = Point(200, 100);
pts[0][4] = Point(100, 100);
const Point *ppts[] = {pts[0]};
int npt[] = {5};
fillPoly(src_bgImg,ppts,npt,1,color,8);
}
void DrawRandomLine()
{
RNG rng(12345);
Point pt1;
Point pt2;
Mat bg_imgs = Mat::zeros(src_bgImg.size(),src_bgImg.type());
namedWindow("randow_window",CV_WINDOW_AUTOSIZE);
for (int i = 0; i < 20000; i++)
{
pt1.x = rng.uniform(0, src_bgImg.cols);
pt2.x = rng.uniform(0, src_bgImg.cols);
pt1.y = rng.uniform(0, src_bgImg.cols);
pt2.y = rng.uniform(0, src_bgImg.cols);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
if (waitKey(100)==27)
{
break;
}
line(bg_imgs, pt1, pt2, color, 1, 8);
imshow("randow_window", bg_imgs);
}
}
十四:随机数和随机颜色
void QuickDemo::random_drawing()
{
Mat canvas = Mat::zeros(Size(512,512), CV_8UC3);
int w = canvas.cols;
int h = canvas.rows;
RNG rng(12345);
while (true)
{
int c = waitKey(10);
if (c == 27)
{
break;
}
int x1 = rng.uniform(0,canvas.cols);
int y1 = rng.uniform(0, h);
int x2 = rng.uniform(0, canvas.cols);
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), 8, LINE_AA,0);
imshow("随机绘制演示", canvas);
}
}
十五:多边形填充和绘制
第一种方式,通过标记各个点,然后存储到容器中,之后对容器中的点进行操作。填充多边形调用fillPoly,绘制多边形调用polylines。第二种方式,使用一个API接口绘制。通过一个容器中的存储的点组成的另一个容器。
void QuickDemo::polyline_drawing_demo(Mat &image)
{
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, 400);
std::vector<Point>pts;
pts.push_back(p1);
pts.push_back(p2);
pts.push_back(p3);
pts.push_back(p4);
pts.push_back(p5);
std::vector<std::vector<Point>>contours;
contours.push_back(pts);
drawContours(canvas,contours,-1, Scalar(0, 0, 255),-1);
imshow("多边形绘制", canvas);
}
十六:鼠标操作和响应
Point sp(-1, -1);
Point ep(-1, -1);
Mat temp;
static void on_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;
std::cout << "start point" <<sp<< std::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);
imshow("ROI区域", image(box));
rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);
imshow("鼠标绘制", image);
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 QuickDemo::mouse_drawing_demo(Mat &image)
{
namedWindow("鼠标绘制", WINDOW_AUTOSIZE);
setMouseCallback("鼠标绘制", on_draw,(void*)(&image));
imshow("鼠标绘制", image);
temp = image.clone();
}
十七:图像像素类型的转换和归一化
void QuickDemo::norm_demo(Mat &image)
{
Mat dst;
std::cout << image.type() << std::endl;
image.convertTo(image,CV_32F);
std::cout << image.type() << std::endl;
normalize(image, dst, 1.0, 0, NORM_MINMAX);
std::cout << dst.type() << std::endl;
imshow("图像的归一化", dst);
}
十八:图像的放缩和差值
void QuickDemo::resize_demo(Mat &image)
{
Mat zoomin, zoomout;
int h = image.rows;
int w = image.cols;
resize(image, zoomin, Size(w/2, h/2),0,0,INTER_LINEAR);
imshow("zoomin", zoomin);;
resize(image, zoomout, Size(w*1.5, h*1.5), 0, 0, INTER_LINEAR);
imshow("zoomin", zoomout);
}
十九:图像的旋转
void QuickDemo::flip_demo(Mat &image)
{
Mat dst;
flip(image, dst, 0);
flip(image, dst, 1);
flip(image, dst, -1);
imshow("图像翻转",dst);
}
二十:图像的翻转
void QuickDemo::rotate_demo(Mat &image)
{
Mat dst, M;
int h = image.rows;
int w = image.cols;
M = getRotationMatrix2D(Point(w / 2, h / 2),45,1.0);
double cos = abs(M.at<double>(0, 0));
double sin = abs(M.at<double>(0, 1));
int nw = cos * w + sin * h;
int nh = sin * w + cos * h;
M.at<double>(0, 2) += (nw / 2 - w / 2);
M.at<double>(1, 2) += (nh / 2 - h / 2);
warpAffine(image, dst, M,Size(nw,nh),INTER_LINEAR,0, Scalar(0, 0, 255));
imshow("旋转演示", dst);
}
二十一:读取视频文件
void QuickDemo::video_demo(Mat &image)
{
VideoCapture capture("D:/images/123.mp4");
Mat frame;
while (true)
{
capture.read(frame);
if(frame.empty())
{
break;
}
imshow("frame", frame);
colorSpace_Demo(frame);
int c = waitKey(100);
if (c == 27) {
break;
}
}
capture.release();
}
二十二:视频处理和保存
视频的属性,SD(标清),HD(高清),UHD(超清),蓝光。如何读取视频文件,以及读取视频文件的属性,衡量视频处理指标:FPS。保存视频时的编码格式。保存视频的实际size和create的size大小保持一致。
void QuickDemo::video_demo(Mat &image)
{
VideoCapture capture("D:/images/123.mp4");
int frame_width = capture.get(CAP_PROP_FRAME_WIDTH);
int frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);
int count = capture.get(CAP_PROP_FRAME_COUNT);
double fps = capture.get(CAP_PROP_FPS);
std::cout << "frame width" << frame_width << std::endl;
std::cout << "frame height" << frame_height << std::endl;
std::cout << "frame FPS" << fps << std::endl;
std::cout << "frame count" << count << std::endl;
VideoWriter writer("D:/test.mp4",capture.get(CAP_PROP_FOURCC),fps,Size(frame_width, frame_height),true);
Mat frame;
while (true)
{
capture.read(frame);
if(frame.empty())
{
break;
}
imshow("frame", frame);
colorSpace_Demo(frame);
writer.write(frame);
int c = waitKey(100);
if (c == 27) {
break;
}
}
capture.release();
writer.release();
}
二十三:直方图
#include
#include "opencv2/opencv.hpp"
#include
using namespace std;
using namespace cv;
Mat src, hsv_src;
Mat hue;
int bins = 12;
void Hist_And_Backprojection(int, void*);
int main()
{
src = imread("E:/QTFiles/firsttext/fish.jpg");
if (!src.data)
{
cout << "could not load image...\n";
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
cvtColor(src, hsv_src, CV_BGR2HSV);
hue.create(hsv_src.size(), hsv_src.depth());
int nchannels[] = { 0,0 };
mixChannels(&hsv_src, 1, &hue, 1, nchannels, 1);
createTrackbar("Histogram Bins:", "input", &bins, 180, Hist_And_Backprojection);
Hist_And_Backprojection(0, 0);
imshow("input", src);
return 0;
}
void Hist_And_Backprojection(int, void*)
{
float range[] = { 0,180 };
const float *histRanges = { range };
Mat h_hist;
calcHist(&hue, 1, 0, Mat(), h_hist, 1, &bins, &histRanges, true, false);
normalize(h_hist, h_hist, 0, 255, NORM_MINMAX, -1, Mat());
Mat backProjectIamge;
calcBackProject(&hue, 1, 0, h_hist, backProjectIamge, &histRanges, 1, true);
namedWindow("BackProjectIamge", CV_WINDOW_AUTOSIZE);
imshow("BackProjectIamge", backProjectIamge);
int hist_h = 400;
int hist_w = 400;
int bin_w = (hist_w / bins);
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
for (size_t i = 1; i < static_cast<size_t>(bins); i++)
{
rectangle(histImage,
Point((i - 1)*bin_w, (hist_h - cvRound(h_hist.at<float>(i - 1)*(400 / 255)))),
Point(i*bin_w, (hist_h - cvRound(h_hist.at<float>(i)*(400 / 255)))),
Scalar(0, 0, 255), 2, LINE_AA);
}
imshow("Histogram", histImage);
waitKey(0);
}
#include
#include
#include
using namespace cv;
using namespace std;
const char*output = "histogram iamge";
int main()
{
Mat src, dst, dst1;
src=imread("E:\\QTFiles\\zhhpicture\\zhh.jpg");
if(src.empty())
{
cout<<"imread wrong!"<<endl;
}
char input[] = "input image";
namedWindow(input, CV_WINDOW_AUTOSIZE);
namedWindow(output, CV_WINDOW_AUTOSIZE);
imshow(input, src);
vector<Mat>bgr_planes;
split(src, bgr_planes);
int histsize = 256;
float range[] = { 0,256 };
const float*histRanges = { range };
Mat b_hist, g_hist, r_hist;
calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histsize, &histRanges, true, false);
calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histsize, &histRanges, true, false);
calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histsize, &histRanges, true, false);
int hist_h = 400;
int hist_w = 512;
int bin_w = hist_w / histsize;
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
for (int i = 1; i < histsize; i++)
{
line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(b_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, CV_AA);
line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(g_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, CV_AA);
line(histImage, Point((i - 1)*bin_w, hist_h - cvRound(r_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, CV_AA);
}
imshow(output, histImage);
waitKey(0);
return 0;
}
二十四:直方图的均衡化
均衡化的图像只支持单通道。
void QuickDemo::histogram_eq_demo(Mat &image)
{
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
imshow("灰度图像", gray);
Mat dst;
equalizeHist(gray, dst);
imshow("直方图均衡化", dst);
}
二十五:图像的卷积操作
卷积的作用,高的往下降,低的往上升。但是会造成信息丢失。产生模糊效果。是一种线性操作,点乘,之后相加。
void QuickDemo::blur_demo(Mat &image)
{
Mat dst;
blur(image, dst, Size(15, 15), Point(-1, -1));
imshow("图像卷积操作", dst);
}
二十六:模糊处理
高斯模糊
中心的数值最大,离中心距离越远,数值越小。
高斯卷积数学表达式说明:
void QuickDemo::gaussian_blur_demo(Mat &image)
{
Mat dst;
GaussianBlur(image, dst, Size(5, 5), 15);
imshow("高斯模糊", dst);
}
高斯双边模糊
void QuickDemo::bifilter_demo(Mat &image)
{
Mat dst;
bilateralFilter(image,dst,0,100,0);
namedWindow("双边模糊", WINDOW_FREERATIO);
imshow("双边模糊", dst);
}
二十七:在一幅图片上加logo
1、在左上角加
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat image1=imread("E:\\QTFiles\\zhhpicture\\zhh.jpg");
Mat image2=imread("E:\\QTFiles\\zhhpicture\\name.png");
imshow("initial image",image1);
Mat roi =image1(Rect(0,0,image2.cols,image2.rows));
Mat mask(image2);
image2.copyTo(roi,mask);
imshow("image2",image2);
imshow("mask img1",image1);
waitKey(0);
return 0;
}
2、在中间加
int x, y;
x = image1.cols / 2 - image2.cols / 2;
y = image1.rows / 2 - image2.rows / 2;
Mat roi = image1(Rect(x, y, image2.cols, image2.rows));
二十八:Mat类型和QImage类型之间的转换
Mat->QImage
QImage cvMat2QImage(const cv::Mat& mat)
{
if(mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for(int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
uchar *pSrc = mat.data;
for(int row = 0; row < mat.rows; row ++)
{
uchar *pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
else if(mat.type() == CV_8UC3)
{
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if(mat.type() == CV_8UC4)
{
qDebug() << "CV_8UC4";
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
qDebug() << "ERROR: Mat could not be converted to QImage.";
return QImage();
}
}
cv::Mat QImage2cvMat(QImage image)
{
cv::Mat mat;
qDebug() << image.format();
switch(image.format())
{
case QImage::Format_ARGB32:
case QImage::Format_RGB32:
case QImage::Format_ARGB32_Premultiplied:
mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
break;
case QImage::Format_RGB888:
mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
cv::cvtColor(mat, mat, CV_BGR2RGB);
break;
case QImage::Format_Indexed8:
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
break;
}
return mat;
}
QImage->Mat
image2=image2.convertToFormat(QImage::Format_RGB888);
Mat image1=Mat(image2.height(),image2.width(),CV_8UC(3),image2.bits(),image2.bytesPerLine());
未完待续
遇到更多我会继续添加
Original: https://blog.csdn.net/qq_46338854/article/details/124474669
Author: &*Savior
Title: OpenCV基础学习
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/704547/
转载文章受原作者版权保护。转载请注明原作者出处!