1:內容介紹
本節主要介紹OpenCV的HighGUI模塊,并分享幾個例子:
1. 用imwrite函數生成png透明圖
2. 綜合示例程序:圖象的載入、顯示與輸出
3. 為程序界面添加滑動條
4. 鼠標操作
2:學習筆記
1. 使用OpenCV首先要學會使用它的圖形界面,此章節介紹了OpenCV的1些HighGUI使用方法,其實不觸及甚么理論部份。關于HighGUI大家可參考官網HighGUI模塊 http://docs.opencv.org/3.1.0/d7/dfc/group__highgui.html ,這里也只是講了其中1部份。
2. 這里推薦1個非常好用的調試進程中圖片查看插件Image Watch:http://blog.csdn.net/nnnnnnnnnnnny/article/details/52260370 。
3. 下面代碼中用到了ROI(region of interest),注意它的構造方式。ROI重新設定了局部坐標,且并沒有分配新的內存。
4. 這里順便穿插1下OpenCV 中Mat類型的深拷貝、淺拷貝,參見:http://www.voidcn.com/blog/qq_23968185/article/p⑸792518.html , http://blog.csdn.net/xiaxiazls/article/details/50018207
5. 下文代碼中也用到了saturate_cast 模板函數,為避免數據不公道的數據轉換,類似于C++中的static_cast等強迫類型轉換。可參見:http://blog.csdn.net/mvtechnology/article/details/8139272
6. 本節函數清單
3:相干源碼及解析
1. 用imwrite函數生成png透明圖
源碼:
#include<opencv2/opencv.hpp>
#include<vector>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat mat(480, 640, CV_8UC4); //創建帶alpha通道的Mat
for (int i = 0; i < mat.rows; i++) {
for (int j = 0; j < mat.cols; j++) {
Vec4b& rgba = mat.at<Vec4b>(i, j);
rgba[0] = UCHAR_MAX;
rgba[1] = saturate_cast<uchar>((float(mat.cols-j))/((float)mat.cols)*UCHAR_MAX);
//為何上面的函數會用到saturate_cast呢,由于不管是加是減,乘除,都會超越1個像素灰度值的范圍(0~255)所以,所以當運算完以后,結果為負,則轉為0,結果超越255,則為255
rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows)*UCHAR_MAX);
rgba[3] = saturate_cast<uchar>(0.5*(rgba[1]+rgba[2]));
// rgba[3] = 0;
}
}
vector<int> compression_params = { IMWRITE_PNG_COMPRESSION, 9 };
try {
imwrite("透明Alpha值圖.png", mat, compression_params);
imshow("【生成的png圖】", mat);
cout << "PNG圖象保存終了,可在工程目錄下看到" << endl;
}
catch (runtime_error& ex) {
cout << "圖象生成產生毛病:" << ex.what() << endl;
}
waitKey(0);
return 0;
}
素材:
無
效果圖:
透明Alpha值圖.png
提示:
無
2. 綜合示例程序:圖象的載入、顯示與輸出
源碼:
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat girl = imread("poster_girl.jpg");
imshow("【動漫畫】", girl);
Mat dota = imread("poster_dota.jpg");
Mat logo = imread("poster_dota_logo.jpg");
imshow("【原圖】", dota);
imshow("【logo圖】", logo);
Mat imageROI;
imageROI = dota(Rect(800, 350, logo.cols, logo.rows));
addWeighted(imageROI, 0.5, logo, 0.3, 0, imageROI);
imshow("【原圖+logo圖】", dota);
imwrite("poster_dota_logo_overlay.jpg", dota);
waitKey(0);
return 0;
}
素材:
poster_girl.jpg
poster_dota.jpg
poster_dota_logo.jpg
效果圖:
poster_dota_logo_overlay.jpg
提示:
此程序中用到了ROI,ROI是重新設定局部坐標
3. 為程序界面添加滑動條
源碼:
#include<opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "【線性混合示例】"
const int g_nMaxAlphaValue = 100; //Alpha最大值
int g_nAlphaValueSlider=70; //滑動條對應的變量,初始值70
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
void on_Tracker(int, void*);
int main()
{
g_srcImage1 = imread("poster_spring_1.jpg");
g_srcImage2 = imread("poster_spring_2.jpg");
namedWindow(WINDOW_NAME); //此處1定要先創建窗體,否則Trackbar沒法顯示
String TrackbarName("透明值");
createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Tracker);
on_Tracker(g_nAlphaValueSlider, 0);
waitKey(0);
return 0;
}
void on_Tracker(int, void*)
{
g_dAlphaValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
g_dBetaValue = 1.0 - g_dAlphaValue;
addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0, g_dstImage);
imshow(WINDOW_NAME, g_dstImage);
}
素材:
poster_spring_1.jpg
poster_spring_2.jpg
效果圖:
提示:
無
4. 鼠標操作
源碼:
#include<opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "【程序窗口】"
void on_MouseHandle(int event, int x, int y, int flags, void* param);
Rect g_rectangle=Rect(-1, -1, 0, 0);
bool g_bDrawingBox = false; //是不是進行繪制
RNG g_rng; //生成隨機函數的類
int main()
{
Mat srcImage(600, 800, CV_8UC3, Scalar::all(0)), tempImage;
srcImage.copyTo(tempImage);
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
while (1){
srcImage.copyTo(tempImage);
if (g_bDrawingBox)
rectangle(tempImage, g_rectangle.tl(), g_rectangle.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
imshow(WINDOW_NAME, tempImage);
if (waitKey(10) == 27) //按下ESC鍵
break;
}
return 0;
}
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(Mat*)param;
switch (event)
{
//鼠標移動消息
case EVENT_MOUSEMOVE:
{
if (g_bDrawingBox)
{
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}
break;
//左鍵按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);
}
break;
//左鍵抬起消息
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false; //置標識符為false
//對寬和高小于0的處理
if (g_rectangle.width<0) {
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
}
if (g_rectangle.height<0) {
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
rectangle(image, g_rectangle.tl(), g_rectangle.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));
}
break;
}
}
素材:
無
效果圖:
提示:
無
上一篇 Java NIO 學習總結
下一篇 Windows-SSD配置與測試