醫(yī)療網(wǎng)站不備案百度熱搜榜排名今日頭條
打開視頻或攝像頭
打開指定視頻
/*VideoCapture(const String &filename, apiPreference);filename:讀取的視頻或者圖像序列的名稱apiPreference:讀取數(shù)據(jù)時設(shè)置的屬性*/
VideoCapture video; //定義一個空的視頻對象
video.open("H:/BaiduNetdiskDownload/01.mp4");
// 判斷視頻有沒有成功打開if (!video.isOpened()) {cout << "視頻打開失敗";return -1;}
打開攝像頭
VideoCapture video(1); //打開一個攝像頭
視頻的相關(guān)操作
通過get獲取視頻數(shù)據(jù)
將視頻流賦值給mat對象
Mat mat;video >> mat; bool isColor = (mat.type() == CV_8UC3); //判斷視頻是否為3通道彩色
輸出視頻的幀率
VideoWriter 視頻寫入
filename:保存視頻的地址和文件名,包含視頻格式
fourcc:壓縮幀的4字符編解碼器代碼
fps:保存視頻的幀率,即視頻中每秒圖像的張數(shù)
framSize:視頻幀的尺寸
isColor:保存視頻是否為彩色視頻
VideoWriter writer;int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); //選擇MJPG的編碼格式double fps = 25.0; //設(shè)置視頻的幀率string filename = "file.avi"; // 視頻的名和格式writer.open(filename, codec, fps, mat.size(),isColor); //創(chuàng)建保存文件的視頻流if (!writer.isOpened()) { // 判斷視頻流是否正常打開cout << "視頻打開失敗";return -1;}
捕捉攝像頭中內(nèi)容,寫入倒視頻中
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>#pragma comment(lib,"opencv_world4100d.lib")using namespace std;
using namespace cv;int main(int argc, char** argv) {// 創(chuàng)建一個 VideoCapture 對象,參數(shù) 0 表示默認(rèn)攝像頭VideoCapture cap(0);// 檢查攝像頭是否成功打開if (!cap.isOpened()) {std::cerr << "Error: Could not open the camera." << std::endl;return -1;}// 獲取攝像頭的幀寬度和高度int frame_width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));int frame_height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));double fps = cap.get(cv::CAP_PROP_FPS);// 幀率不能小于0if (fps <= 0) fps = 30.0;std::string output_file = "F:/output.avi";int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D');cv::VideoWriter writer(output_file, fourcc, fps, cv::Size(frame_width, frame_height));if (!writer.isOpened()) {std::cerr << "Error: Could not open the output video file for write." << std::endl;return -1;}// 創(chuàng)建一個窗口來顯示視頻cv::namedWindow("Camera Feed", cv::WINDOW_AUTOSIZE);while (true) {cv::Mat frame;// 捕獲一幀cap >> frame;// 檢查幀是否為空if (frame.empty()) {std::cerr << "Error: Blank frame grabbed." << std::endl;break;}// 顯示幀cv::imshow("Camera Feed", frame);writer.write(frame);// 檢查是否按下了 'q' 鍵來退出循環(huán)if (cv::waitKey(10) == 'q') {break;}}// 釋放攝像頭并關(guān)閉所有窗口cap.release();writer.release();cv::destroyAllWindows();return 0;
}
顏色空間轉(zhuǎn)換
三種存取數(shù)據(jù)的區(qū)間
- 8U–存儲0-255的數(shù)據(jù)類型
- 32F–存儲0-1(將0-1區(qū)間映射為0-255,大于1的部分映射為白色,小于0的部分映射為黑色)
- 64F–存儲0-1
convertTo
m:輸出圖像
rtype:轉(zhuǎn)換后數(shù)據(jù)類型
alpha:縮放系數(shù)
beta:平移系數(shù)
轉(zhuǎn)換公式:alpha*I(x,y)+ beta
// 將0-255的圖像轉(zhuǎn)為0-1mat.convertTo(mat2, CV_32F, 1/255.0, 0);
RGB轉(zhuǎn)灰度圖公式:Gray=R0.3+G0.59+B*0.11
圖像格式轉(zhuǎn)換cvtColor
src:待轉(zhuǎn)換顏色模型的原始圖像
dst:轉(zhuǎn)換顏色模型后的目標(biāo)圖像。
code:顏色空間轉(zhuǎn)換的標(biāo)志,如由RGB空間到HSV空間。
dstCn:目標(biāo)圖像中的通道數(shù),如果參數(shù)為0,則從src和代碼中自動導(dǎo)出通道數(shù)。
Mat HSV;// 將RGB轉(zhuǎn)為HSVcvtColor(mat, HSV, COLOR_BGR2HSV);
圖像轉(zhuǎn)換
CV_BGR2GRAY:將BGR格式的圖像轉(zhuǎn)換為灰度圖。
CV_BGR2HSV:將BGR格式的圖像轉(zhuǎn)換為HSV格式。
CV_BGR2LAB:將BGR格式的圖像轉(zhuǎn)換為LAB格式。
CV_BGR2Luv:將BGR格式的圖像轉(zhuǎn)換為Luv格式。
CV_BGR2RGB:將BGR格式的圖像轉(zhuǎn)換為RGB格式(注意,OpenCV默認(rèn)讀取的圖像是BGR格式,所以這個函數(shù)在某些情況下很有用)。
CV_BGR2XYZ:將BGR格式的圖像轉(zhuǎn)換為XYZ格式。
CV_BGR2YUV:將BGR格式的圖像轉(zhuǎn)換為YUV格式。
CV_BGR2YCrCb:將BGR格式的圖像轉(zhuǎn)換為YCrCb格式。
通道管理
split多通道分離
split(
InputArray m, //可以輸入mat型
OutputArrayOfArrays mv
)
m:待分離的多通道圖像
mv:分離后的單通道圖像,為向量vector形式
merge多通道合并
merge(
InputArrayOfArrays mv,
OutputArray dst )
mv:需要合并的圖像向量vector,其中每個圖像必須擁有相同的尺寸和數(shù)據(jù)類型
dst:合并后輸出的圖像,通道數(shù)等于所有輸入圖像的通道數(shù)的總和
合并兩個矩陣,取同一位置中較小的值
min(
InputArray src1,
InoytArray sec2,
OutputArray dst )
合并兩個矩陣,取同一位置中較大的值
max(
InputArray src1,
InoytArray sec2,
OutputArray dst )
找出矩陣中的最值
minMaxLoc(
InputArray src, //輸入單通道矩陣
CV_OUT double* minVal, //指向最小值的指針,如果不需要,則使用NULL
CV_OUT double* maxVal =0, //指向最大值的指針,如果不需要,則使用NULL
CV_OUT Point* minLoc =0, //指向最小值位置的指針,如果不需要,則使用NULL
CV_OUT Point* maxLoc = 0, //指向最大值位置的指針,如果不需要,則使用NULL
InputArray mask =noArray() //掩碼矩陣,用于標(biāo)記尋找上述四個值的范圍,參數(shù)默認(rèn)值為noArray,表示尋找范圍是矩陣中所有數(shù)據(jù)
)
與或非運算
非運算
bitwise_not( //非運算InputArray src, //輸入矩陣OutputArray dst, //輸出矩陣InputArray mask = noArray() //掩碼區(qū)域
)
與運算
bitwise_and( //與運算InputArray src1, //輸入矩陣1InputArray src2, //輸入矩陣2OutputArray dst, // 輸出矩陣InputArray mask = noArray());//掩碼矩陣
或運算
bitwise_or( //或運算InputArray src1, //輸入矩陣1InputArray src2, //輸入矩陣2OutputArray dst, // 輸出矩陣InputArray mask = noArray());//掩碼矩陣
)
閾值化(二值化)
threshold( //圖像二值化
InputArray src, //待二值化圖像,圖像只能是CV_8U和CV_32F兩種數(shù)據(jù)類型
OutputArray dst, //二值化后的圖像
double thresh, //閾值
double maxval, //二值化過程中的最大值,非必須參數(shù)
int type //二值化方式
);
adaptiveThreshold( //自適應(yīng)閾值化,只支持灰度圖InputArray src, //待二值化圖像OutputArray dst, //輸出圖像double maxValue, //二值化的最大值int adaptiveMethod, //自適應(yīng)確定閾值的方法,分為均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_Cint thresholdType, //選擇二值化方法int blockSize, //自適應(yīng)確定閾值的像素鄰域大小double C); //從平均值或者加權(quán)平均值中減去的常數(shù)
LUT查找表
LUT(
InputArray src, //輸入圖像,類型只能是8U
InputArray lut, //256個像素的查找表,如果為多通道,通道數(shù)必須和輸入圖像通道數(shù)相同
OutputArray dst //輸出矩陣,數(shù)據(jù)類型和查找表相同
);
圖像尺寸縮放、翻轉(zhuǎn)、拼接
圖像尺寸縮放
resize(InputArray src, //輸入圖像OutputArray dst, //輸出圖像Size dsize, //輸出圖像的尺寸double fx = 0, //水平軸的比例因子,變?yōu)樵瓉淼膸妆禿ouble fy = 0, //垂直軸的比例因子int interpolation = INTER_LINEAR //插值方法,INTER_AREA最近鄰插值,INTER_LINEAR雙線性插值,INTER_CUBIC三線性插值
);flip( 圖像翻轉(zhuǎn)InputArray src, //輸入圖像OutputArray dst, //輸出圖像int flipCode //翻轉(zhuǎn)方式標(biāo)志,數(shù)值大于0表示繞y軸翻轉(zhuǎn),數(shù)值等于0表示圍繞x軸翻轉(zhuǎn),數(shù)值小于0表示圍繞兩個軸翻轉(zhuǎn)
);
resize(INTER_AREA,INTER_LINEAR,INTER_CUBIC)hconcat(//橫向拼接InputArray src1, // 輸入圖像 InputArray src2, //輸入圖像,需要兩個輸入圖像高度相同OutputArray dst //輸出圖像
) vconcat(//縱向拼接InputArray src1, // 輸入圖像 InputArray src2, //輸入圖像,需要兩個輸入圖像高度相同OutputArray dst //輸出圖像
)
仿射變換和旋轉(zhuǎn)
// 仿射變換:由平移,縮放,旋轉(zhuǎn),翻轉(zhuǎn)和錯切組合得到,也叫三點變換
warpAffine( 仿射變換InputArray src, //輸入圖像OutputArray dst, //輸出圖像InputArray M, //2*3變換矩陣,仿射變換矩陣Size dsize, //輸出圖像尺寸int flags = INTER_LINEAR, //插值方法標(biāo)志int borderMode = BORDER_CONSTANT, //像素邊界外推方法的標(biāo)志const Scalar& borderValue = Scalar()); //填充邊界使用的數(shù)值,默認(rèn)情況下為0
像素邊界外推方法
BORDER_CONSTANT = 0,用特定值填充//!< iiiiii|abcdefgh|iiiiiii
BORDER_REPLICATE = 1,兩端復(fù)制填充//!< aaaaaa|abcdefgh|hhhhhhh
BORDER_REFLECT = 2, 倒敘填充//!< fedcba|abcdefgh|hgfedcb
BORDER_WRAP = 3, 正序填充//!< cdefgh|abcdefgh|abcdefg
BORDER_REFLECT_101 = 4, 不包含邊界值倒敘填充//!< gfedcb|abcdefgh|gfedcba
BORDER_TRANSPARENT = 5, //隨機填充!< uvwxyz|abcdefgh|ijklmno
BORDER_REFLECT101 = BORDER_REFLECT_101, //!與BORDER_REFLECT_101相同
BORDER_DEFAULT = BORDER_REFLECT_101, //!與BORDER_REFLECT_101相同
BORDER_ISOLATED = 16 //!< 不關(guān)心感興趣區(qū)域之外的部分
c++中并沒有直接進行圖像旋轉(zhuǎn)的函數(shù),需要求取一個旋轉(zhuǎn)變換的仿射矩陣,通過仿射矩陣實現(xiàn)圖像的旋轉(zhuǎn)
getRotationMatrix2D( 圖像旋轉(zhuǎn),返回一個2*3的矩陣
Point2f center, 圖像旋轉(zhuǎn)的中心位置
double angle, 圖像旋轉(zhuǎn)的角度,正值為逆時針旋轉(zhuǎn)
double scale 兩個軸的比例因子,可以實現(xiàn)旋轉(zhuǎn)過程中的圖像縮放,不縮放輸入1
);
圖像旋轉(zhuǎn)的計算公式
三點對應(yīng)方式計算仿射變換矩陣
getAffineTransform(
const Point2f src[], 原圖像的三個點坐標(biāo)
const Point2f dst[] 仿射變換后的三個點坐標(biāo)
);
透視變換(透視投影,又叫四點變換)
從一個點出發(fā)把一個平面內(nèi)人形狀投影到另一個平面上
計算公式:
getPerspectiveTransform( 計算透視變換矩陣
const Point2f src[], 原圖像中的三個坐標(biāo)
const Point2f dst[], 目標(biāo)圖像中的三個像素坐標(biāo)
int solveMethod = DECOMP_LU 計算透視變換矩陣的方法
);
計算透視變換矩陣的方法DECOMP_LU = 0, 最佳主軸元素的高斯消元法 DECOMP_SVD = 1, 奇異值分解法 DECOMP_EIG = 2, 特征值分解法 DECOMP_CHOLESKY = 3, Cholesky分解法DECOMP_QR = 4, QR分解法DECOMP_NORMAL = 16 使用正規(guī)方程公式,可以去前面的標(biāo)志一起使用warpPerspective( 透視變換函數(shù)InputArray src, 輸入圖像OutputArray dst,InputArray M, 3*3的透視變換矩陣Size dsize, 輸出圖像尺寸int flags = INTER_LINEAR, 插值方式 int borderMode = BORDER_CONSTANT, 像素邊界外推方法的標(biāo)志 const Scalar& borderValue = Scalar() 填充邊界使用的數(shù)值,默認(rèn)為0);
繪制圖形
繪制直線
line( InputOutputArray img, //繪制的圖像Point pt1, //起點坐標(biāo)Point pt2, //終點坐標(biāo)const Scalar& color, //顏色int thickness = 1, //寬度int lineType = LINE_8, //邊界類型int shift = 0 //中心坐標(biāo)的半徑數(shù)值中的小數(shù)點數(shù)
);
邊界類型:
FILLED = -1, 填充型LINE_4 = 4, //!< 4-connected line 四連接LINE_8 = 8, //!< 8-connected line 8連接LINE_AA = 16 //!< antialiased line
繪制圓形
circle(InputOutputArray img, Point center, int radius, 半徑長度const Scalar& color, int thickness = 1, 線的寬度,-1為繪制實心圓int lineType = LINE_8,int shift = 0
);
繪制橢圓
ellipse(InputOutputArray img, Point center,Size axes,double angle, //橢圓旋轉(zhuǎn)的角度double startAngle, 起始角度double endAngle, 終止角度const Scalar& color,int thickness = 1,int lineType = LINE_8, int shift = 0);
矩形繪制
rectangle(InputOutputArray img,Point pt1, Point pt2,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);
繪制多邊形
fillPoly(InputOutputArray img, const Point** pts, 所有頂點坐標(biāo)(可以是多重數(shù)組,繪制多個多邊形)const int* npts, 定點數(shù)int ncontours, 繪制的多邊形的個數(shù)const Scalar& color, int lineType = LINE_8, int shift = 0,Point offset = Point());
繪制文字
putText(InputOutputArray img, const String& text, Point org, //文字字符串左下角像素的坐標(biāo)int fontFace, double fontScale, Scalar color,int thickness = 1, int lineType = LINE_8,bool bottomLeftOrigin = false
);
ROI分割和拷貝
img(Range(int start, //區(qū)間的開始int end; //區(qū)間的結(jié)束 ),Range(int start, //區(qū)間的開始int end; //區(qū)間的結(jié)束 )
)Rect_(_Tp _x, //左上角x坐標(biāo)_Tp _y, //左上角y坐標(biāo)_Tp _width, //寬_Tp _height) //高
矩陣存儲圖
淺拷貝:只拷貝矩陣頭
mat1=mat2
深拷貝:拷貝所有內(nèi)容
cv::copyTo
copyTo(InputArray src,OutputArray dst, InputArray mask);Mat::copyToMat mat1;mat.copyTo(OutputArray dst,InputArray mask) const
圖像金字塔
高斯圖像金字塔:不斷下采樣
拉普拉斯金字塔:第k層的高斯圖像下采樣,再上采樣,然后上采樣和第k層的高斯圖像求和得到拉普拉斯金字塔
pyrDown( //下采樣InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT //填充方式);pyrUp( 上采樣InputArray src,OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT);
創(chuàng)建滑動條和鼠標(biāo)監(jiān)控
創(chuàng)建滑動條
createTrackbar(const String& trackbarname, const String& winname, //創(chuàng)建滑動條的窗口的名稱int* value, //反應(yīng)當(dāng)前滑塊的位置int count, //最大值TrackbarCallback onChange = 0, //回調(diào)函數(shù)void* userdata = 0 //傳遞給回調(diào)函數(shù)的參數(shù));
案例代碼
Mat img;void callBack(int value, void*) {float a = value / 100;Mat img2 = img * a;imshow("img", img2);
}int main()
{img = imread("H:/1732413934315.png");namedWindow("img");imshow("img", img);int value = 100;createTrackbar("滑動條名稱","img",&value,200,callBack,0);waitKey(0);return 0;
}
鼠標(biāo)監(jiān)控
setMouseCallback( 鼠標(biāo)時間響應(yīng)函數(shù)const String& winname, MouseCallback onMouse, void* userdata = 0)MouseCallback(int event, 鼠標(biāo)響應(yīng)事件標(biāo)志,瞬間動作int x, int y, int flags, 鼠標(biāo)相應(yīng)標(biāo)識,長時間的操作void* userdata 傳遞給回調(diào)函數(shù)的可選參數(shù))鼠標(biāo)響應(yīng)時間標(biāo)志enum MouseEventTypes {EVENT_MOUSEMOVE = 0, //!< 鼠標(biāo)指針再窗口上移動EVENT_LBUTTONDOWN = 1, //!<按下鼠標(biāo)左鍵EVENT_RBUTTONDOWN = 2, //!< 按下鼠標(biāo)右鍵EVENT_MBUTTONDOWN = 3, //!< 按下鼠標(biāo)中鍵EVENT_LBUTTONUP = 4, //!< 釋放鼠標(biāo)左鍵EVENT_RBUTTONUP = 5, //!< 釋放鼠標(biāo)右鍵EVENT_MBUTTONUP = 6, //!< 釋放鼠標(biāo)中鍵EVENT_LBUTTONDBLCLK = 7, //!< 雙擊鼠標(biāo)左鍵EVENT_RBUTTONDBLCLK = 8, //!< 雙擊鼠標(biāo)右鍵EVENT_MBUTTONDBLCLK = 9, //!< 雙擊鼠標(biāo)中鍵EVENT_MOUSEWHEEL = 10,//!< 正值表示向前滾動,負(fù)值表示向后滾動EVENT_MOUSEHWHEEL = 11 //!< 正值表示向左滾動,負(fù)值表示向右滾動鼠標(biāo)相應(yīng)標(biāo)識EVENT_FLAG_LBUTTON = 1, //!< 按住左鍵拖拽EVENT_FLAG_RBUTTON = 2, //!< 按住右鍵拖拽EVENT_FLAG_MBUTTON = 4, //!< 按住中鍵拖拽EVENT_FLAG_CTRLKEY = 8, //!< 按下ctrl鍵EVENT_FLAG_SHIFTKEY = 16,//!< 按下SHIFT鍵EVENT_FLAG_ALTKEY = 32 //!< 按下ALT鍵normalize( 歸一化InputArray src, OutputArray dst, double alpha = 0, double beta = 1, int norm_type = NORM_MINMAX, int dtype = -1, InputArray mask = noArray()
);NORM_MINMAX: 數(shù)組的數(shù)值被線性變換到alpha和beta之間(通常是0到1)。NORM_L2 : :歸一化后的值 = 像素值 / sqrt(所有像素值平方和)NORM_INF : 歸一化后的值 = 像素值 / 最大絕對值像素值NORM_L1 : 歸一化后的值 = 像素值 / (所有像素值絕對值的和)calcHist( 統(tǒng)計圖像像素const Mat* images,int nimages,const int* channels, //需要統(tǒng)計哪些區(qū)域InputArray mask,SparseMat& hist, int dims,const int* histSize, const float** ranges, //每個圖像通道中灰度值的取值范圍bool uniform = true, //直方圖是否均勻bool accumulate = false //是否累積統(tǒng)計直方圖,是否分別統(tǒng)計每個通道
);equalizeHist( 直方圖均衡化InputArray src, 輸入圖像必須是8UC1OutputArray dst);LUTLUT(圖像直方圖匹配,將圖像分布映射為指定分布InputArray src, InputArray lut, 變換矩陣OutputArray dst
);matchTemplate(InputArray image, 只能為8U或32F格式,兩個輸入圖像類型必須相同InputArray templ,OutputArray result,int method, 匹配方法 InputArray mask = noArray());匹配方法
TM_SQDIFF = 0, 平方差匹配法 TM_SQDIFF_NORMED = 1, 歸一化平方差匹配法 TM_CCORR = 2, 相關(guān)匹配法TM_CCORR_NORMED = 3, 歸一化相關(guān)匹配法 TM_CCOEFF = 4, 系數(shù)匹配法 TM_CCOEFF_NORMED = 5 歸一化相關(guān)系數(shù)匹配法
求積分圖像
integral(InputArray src, OutputArray sum, 標(biāo)準(zhǔn)求和積分圖像OutputArray sqsum, 平方求和積分圖像OutputArray tilted, 傾斜45°積分圖像 int sdepth = -1, 標(biāo)準(zhǔn)求和和傾斜求和積分圖像輸出類型 int sqdepth = -1 平方求和積分圖像數(shù)據(jù)類型
);
漫水填充算法
1. 選擇填充算法步驟
2. 以種子點為中心,判斷4鄰域或8鄰域的像素值與種子點像素值的差值,將差值小于閾值的像素點添加進區(qū)域內(nèi)
3. 將新加入的像素點作為新的種子點,反復(fù)執(zhí)行第二步,知道沒有新的像素點杯添加進區(qū)域
floodFill( InputOutputArray image, InputOutputArray mask,Point seedPoint, Scalar newVal, 歸入種子點區(qū)域內(nèi)像素點的像素值CV_OUT Rect* rect = 0, 種子點漫水填充區(qū)域的最小矩形邊界 Scalar loDiff = Scalar(), 添加進種子點區(qū)域條件的下界差值Scalar upDiff = Scalar(), 添加進種子點區(qū)域條件的上界差值int flags = 4 漫水填充方法
);
分水嶺分割算法
1. 首先對圖像像素的灰度級進行排序,確定灰度值較小的像素點,改像素點即為開始注水點
2. 淹沒過程:對每個最低點開始不斷注水,不斷掩膜周圍的像素點,不同注水處的水匯集在一起,形成分割線watershed(InputArray image, InputOutputArray markers
);
角點檢測
Harris角點
首先定義一個矩形區(qū)域,計算區(qū)域內(nèi)像素值之和,移動區(qū)域,計算像素值之和,如果變化大,認(rèn)為是角點cornerHarris(Harris角點檢測InputArray src, OutputArray dst, int blockSize, 鄰域大小int ksize, sobel算子的半徑 double k, 權(quán)重系數(shù)int borderType = BORDER_DEFAULT
);drawKeypoints(角點繪制InputArray image,const std::vector<KeyPoint>& keypoints, 關(guān)鍵點左邊和方向InputOutputArray outImage,const Scalar& color = Scalar::all(-1),DrawMatchesFlags flags = DrawMatchesFlags::DEFAULT
);