{Emgu}{C#}保存图片、视频等
一、簡介
以前研究所的時候,有使用VC.NET 配合 OpenCV 做影像處理,這東西相當讚,可以省去不少開發時間,今天嘗試看看如何在Visual C# 2008 上使用 OpenCV。
以下引用 OpenCV 中文網站 的介紹
1. 什麼是OpenCV
OpenCV是Intel®開源電腦視覺庫。它由一系列 C 函數和少量 C++ 類構成,實現了圖像處理和電腦視覺方面的很多通用演算法。
2. OpenCV 重要特性
OpenCV 擁有包括 300 多個C函數的跨平臺的中、高層 API。它不依賴於其它的外部庫——儘管也可以使用某些外部庫。
OpenCV 對非商業應用和商業應用都是免費(FREE)的。(細節參考license)。
OpenCV 為Intel®Integrated Performance Primitives (IPP) 提供了透明介面。這意味著如果有為特定處理器優化的的 IPP 庫, OpenCV 將在運行時自動載入這些庫。 更多關於 IPP 的信息請參考:
http://www.intel.com/software/products/ipp/index.htm
3. 體驗OpenCV
的魅力
看了以上對OpenCV的介紹,還是不知道OpenCV在做什麼的話,可以先看這段影片,影片的成果是透過 OpenCV 所撰寫而成。
二、方法
1. 下載與安裝OpenCV
要使用 OpenCV,首先必須要下載並且安裝,點這裡下載 OpenCV_1.1pre1a.exe,下載後執行安裝,安裝過程幾乎都是點選下一步,在此需記住安裝目錄為何,預設為 C:\Program Files\OpenCV。
2. 下載與安裝EmguCV
EmguCV 封裝了 OpenCV image processing library,而且可在.Net平台使用,因此在本文中,透過EmguCV,讓我們可以在 Visual C# 2008 中使用OpenCV。
點選這裡下載Emgu.CV.Binary-1.5.0.1.zip,下載完成後,解壓縮檔案可看EmguCV的DLL檔;我將此目錄放到 C:\Program Files\OpenCV,解壓縮後的檔案只要自己記得就好,因為之後要將這些檔案加入參考。
(1) 下載網頁部份
(2) 下載後解壓縮檔案
3. 新增專案,並且加入相關的參考
先 [ 新增專案 ] -> [ Visual C# ]-> [ WIndows Form 應用程式 ],接著將上個步驟中的 dll加入參考,要加入的參考請參考下圖。
4. 加入 EmguCV的控制項,到工具箱中
主要是將 Emgu.CV.UI.dll加入工具箱中,加入後會出現 ImageBox、HistogramCtrl。
5. 到此,已經將要撰寫OpenCV的工作完成了。開始撰寫程式碼,在這裡示範兩個範例,第一個是開啟並顯示 WebCam
畫面。
5.1 先在Form上拉兩個控制項,分別是Button ( Name : captureButton )與 ImageBox ( Name : captureImageBox )
5.2 撰寫以下程式碼
using System;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// 要引用的類別
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using System.Threading;
namespace MyOpenCV
{
public partial
class Form2 :Form
{
public Form2()
{
InitializeComponent();
}
private Capture_capture;
private
bool_captureInProgress;
private
voidProcessFrame(object sender, EventArgs arg)
{
Image<Bgr,Byte> frame = _capture.QueryFrame();
captureImageBox.Image= frame;
}
private
voidcaptureButton_Click(object sender, EventArgs e)
{
if capture
is not created, create it now
if (_capture!=
null)
{
if(_captureInProgress)
{ //stop thecapture
Application.Idle-=
new EventHandler(ProcessFrame);
captureButton.Text=
"Start Capture";
}
else
{
//start thecapture
captureButton.Text=
"Stop";
Application.Idle+=
new EventHandler(ProcessFrame);
}
_captureInProgress= !_captureInProgress;
}
}
}
}
5.3 執行結果,請注意喔,以下顯示的是 Webcam 即時視訊,不是影像喔
6. 第二個範例,我們將上一個範例,加上灰階、Canny處理
讓大家了解 OpenCV 的強大,而這動作,只需要多拉兩個ImageBox在加上幾行程式就可以了喔,真是太讚了,難怪很多學生想畢業,都用OpenCV
6.1 在上一個範例中,在多拉兩個 ImageBox,Name 分別為grayscaleImageBox、cannyImageBox
6.2 將上一個範例,加上四行程式碼就可以達成將Webcam視訊灰階以及Canny
using System;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// 要引用的類別
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using System.Threading;
namespace MyOpenCV
{
public partial
class Form2 :Form
{
public Form2()
{
InitializeComponent();
}
private Capture_capture;
private
bool_captureInProgress;
private
voidProcessFrame(object sender, EventArgs arg)
{
Image<Bgr,Byte> frame = _capture.QueryFrame();
captureImageBox.Image= frame;
//
請再加上以下四行程式碼
Image<Gray,Byte> grayFrame = frame.Convert<Gray, Byte>();
Image<Gray,Byte> cannyFrame = grayFrame.Canny(new Gray(100),
new Gray(60));
grayscaleImageBox.Image= grayFrame;
cannyImageBox.Image= cannyFrame;
}
private
voidcaptureButton_Click(object sender, EventArgs e)
{
if capture
is not created, create it now
if (_capture!=
null)
{
if(_captureInProgress)
{ //stop thecapture
Application.Idle-=
new EventHandler(ProcessFrame);
captureButton.Text=
"Start Capture";
}
else
{
//start thecapture
captureButton.Text=
"Stop";
Application.Idle+=
new EventHandler(ProcessFrame);
}
_captureInProgress= !_captureInProgress;
}
}
}
}
6.3 執行結果
三、範例下載
http://cid-101d8ba47227b414.skydrive.live.com/self.aspx/.Public/MyOpenCV.rar
四、遇到錯誤 'Emgu.CV.CvInvoke'
的型別初始設定式發生例外狀況
1. 將您的 OpenCV 資料夾路徑與 Emgu 資料夾路徑加入Windows 環境變數。
2. 使用 Visual Studio 開啟您的專案。
(1) 在專案上按滑鼠右鍵,選擇 [屬性] / [參考路徑],加入你的 OpenCV 與 Emgu 的安裝路徑。
(2) 在建置組態中,把平台改成 X86,參考 HOW TO:將專案設定成以平台為目標
转自:http://www.dotblogs.com.tw/chou/archive/2009/06/13/8812.aspx
http://www.cnblogs.com/maiye/archive/2010/06/19/1761075.html
首先介绍一下自己的情况,2010年的3月份开始接触学习C#编程,之前C#和OpenCV都是零基础,由于全都是自学进度比较慢,中间也走了不少
弯路。进过三个月自己的学习与探索,对C#中使用OpenCV也算是有点心得,希望对初学者有所帮助,也希望大牛们进行指点。我使用的编程环境是
VS2005,使用的Emgucv 2.1.0.793版本。
1.先是在程序中图像的导入,我是根据图像路径实现,其中path是string类型,是图像路径。
IntPtr img=CvInvoke.cvLoadImage(path, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_ANYCOLOR);
2.图像灰度化处理,先创建一幅尺寸大小为为原图的8位图像GrayImg1:
Rectangle cr = CvInvoke.cvGetImageROI(img1);
int width = cr.Width;
int height = cr.Height;
IntPtr GrayImg1 = CvInvoke.cvCreateImage(cr.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);
现在就能使用cvCvtColor函数实现灰度化:
CvInvoke.cvCvtColor(img1, GrayImg1, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2GRAY);
3.直方图的创建,并获取数据
int[] hist_size = new int[1] { 256 };//建一个数组来存放直方图数据
IntPtr HistImg=CvInvoke.cvCreateHist(1, hist_size, Emgu.CV.CvEnum.HIST_TYPE.CV_HIST_ARRAY, null, 1);//创建了一个空的直方图
CvInvoke.cvCalcHist(inPtr1,
HistImg,false,System.IntPtr.Zero);//计算inPtr1指向图像的数据,并传入Histimg中,其中
IntPtr[] inPtr1 = new IntPtr[1] { SubImg}。
现在要获取Histimg中的具体数据:
for (int i = 0; i < 256; i++)
{
temphist[i] = CvInvoke.cvQueryHistValue_1D(histImg, i);
}
这样在数组temphist中保存了直方图数据。
4.对第一步中由cvLoadImage导入的图像进行像素点的操作。由于img 是IntPtr类型无法直接进行操作,所以首先要进行格式的转化,把IntPtr型转换成MIplImage:
Emgu.CV.Structure.MIplImage MIpImg =
(Emgu.CV.Structure.MIplImage)System.Runtime.InteropServices.Marshal.PtrToStructure(img, typeof(Emgu.CV.Structure.MIplImage));
然后再C#中使用unsafe中指针操作:npixel = (int)((byte*)img.imageData + img.widthStep * i)[j];
5.在二值话的图像,对不为零的区域经行检测。
IntPtr Dyncontour = new IntPtr();//存放检测到的图像块的首地址
IntPtr Dynstorage = CvInvoke.cvCreateMemStorage(0);开辟内存区域
int n= CvInvoke.cvFindContours(tempimg, Dynstorage, ref
Dyncontour, StructSize.MCvContour,
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_CCOMP,Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE,
new Point(0, 0));
n表示检测到不为零区域的个数。
6.对第五步检测到的区域绘制轮廓
for(;DyncontourTemp!=null&&DyncontourTemp.Ptr.ToInt32()!=0;DyncontourTemp=DyncontourTemp.HNext)
{
CvInvoke.cvDrawContours(tempContImg, DyncontourTemp,new
MCvScalar(255, 255, 255),new MCvScalar(255, 255, 255), 0, 1,
Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
}
其中的DyncontourTemp为
Seq<Point> DyncontourTemp1= new Seq<Point>(Dyncontour, null);//方便对IntPtr类型进行操作
Seq<Point> DyncontourTemp=DyncontourTemp1;
7.对第五步检测出的区域的坐标提取,通过cvFindContours函数的调用在 Dyncontour中存放的是不为零区域坐标的值存储在内存中的首地址指针。
seq<Point> DyncontourTemp1= new Seq<Point>(Dyncontour, null); //方便对IntPtr类型进行操作
int total=contourImg.Total;//contourImg包含的元素的总数
int TempX = 0; int TempY = 0;int[,] contourArray = new int[2,total];
//获得轮廓的坐标值
for (int i = 0; i < total;i++ )
{
contourArray[0,i]=contourImg[i].X;
contourArray[1,i]=contourImg[i].Y;
}
C#下用OPENCV的配置OPENCV
下面是EMGUCV的使用方法:
一 首先下载EmguCV,就是可以在Visual Studio2005/2008中引用OpenCV的函数的dll库。可以到这里下载:http://groups.google.com/group/tim-files/files?upload=1 名为"Emgu.CV.Windows.Binary-1.3.0.0.zip"
二 将文件解压出来,放到哪里都可以,不过建议将解压出来的文件夹放到OpenCV的目录下面,这样不会误删吧,呵呵。
三
当然,在用EmguCV之前,要安装了OpenCV,并且OpenCV的各项配置都配置OK了,我这里说的只是配置EmguCV的。所以,请确保在配置
EmguCV之前你的OpenCV的开发环境已经配置OK了。如果不会,可以看我的一篇文章。就在"学海泛舟篇"中,找找看吧。
四 打开Visual Studio
2005/2008,新建C#的Win32窗体应用程序。然后,点击"项目"-〉"添加引用"-〉"浏览",然后把EmguCV1.3.0目录下的
Emgu.CV.dll Emgu.Util.dll ZedGraph.dll zlib.net.dll
都添加到引用里面,其实也不用全部添加,不过由于我们不知道有些函数在那些dll中,所以索性全添加就可以了。
五 然后,再程序的开头中加上 using Emgu.CV; using Emgu.Util; 之后就可以用EmguCV中所有的库函数了。
六 在窗体上画一个按钮,然后再按纽的下面写上如下的程序:
private void btnOpenImage_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "BMP文件|*.bmp|JPG文件|*.jpg|JPEG文件|*.jpeg|所有文件|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
CvInvoke.cvNamedWindow("打开图片");
IntPtr img =
CvInvoke.cvLoadImage(openFileDialog.FileName,
Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_UNCHANGED);
CvInvoke.cvShowImage("打开图片", img);
this.img = img;
CvInvoke.cvWaitKey(0);
CvInvoke.cvReleaseImage(ref img);
CvInvoke.cvDestroyWindow("打开图片");
}
}
这样,我们就能用OpenCv的函数来打开和显示一个图片了。如果要保存图片可以如下:
private void btnSaveImage_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "BMP文件|*.bmp|JPG文件|*.jpg|JPEG文件|*.jpeg|所有文件|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
CvInvoke.cvSaveImage(saveFileDialog.FileName, this.img);
}
}
如果要打开一个AVI视频文件,可以如下:
private void btnOpenAVI_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "AVI文件|*.avi";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
CvInvoke.cvNamedWindow("打开视频");
IntPtr capture=CvInvoke.cvCreateFileCapture(openFileDialog.FileName);
this.video = capture;
IntPtr frame = new IntPtr();
while (true)
{
frame = CvInvoke.cvQueryFrame(capture);
CvInvoke.cvShowImage("打开视频", frame);
//if (!frame) break;
int c = CvInvoke.cvWaitKey(20);
if (c == 13) break;
}
//this.video = capture;
CvInvoke.cvWaitKey(0);
CvInvoke.cvReleaseCapture(ref capture);
CvInvoke.cvDestroyWindow("打开视频");
}
}
要保存一个AVI文件可以如下:
private void btnSaveAVI_Click(object sender, EventArgs e)
{
IntPtr avi = this.video;
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "BMP文件|*.bmp|JPG文件|*.jpg|JPEG文件|*.jpeg|所有文件|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
IntPtr videoWriter =
CvInvoke.cvCreateVideoWriter(saveFileDialog.FileName, -1, 20, new
Emgu.CV.MCvSize(480, 500), 1);
IntPtr capture=CvInvoke.cvCreateFileCapture(saveFileDialog.FileName);
IntPtr frame = new IntPtr();
while (true)
{
frame = CvInvoke.cvQueryFrame(capture);
CvInvoke.cvWriteFrame(videoWriter, frame);
}
}
}
注意上面的保存AVI和打开AVI文件还存在问题:就是在AVI文件结尾处,如何退出的问题。在C++里面我们可以用if(!frame)
break;来退出。但是在C#中这样是不行的,因为在C#中图片的类型是IntPtr类型。所以,在打开AVI文件的程序中,我用了
cvWaitKey()的返回值来退出播放AVI文件。而在保存中没有设置什么时候保存完毕,所以,保存AVI文件会出现问题。不过,只是提供了一种思路
罢了。
Opencv C# 学习之一 打开图片
http://blog.sina.com.cn/s/blog_6174faf60100gg7u.html
在C#中写一段代码,打开一副图像并显示出来。
1、新建一个C#工程;
2、程序的开头中加上 using Emgu.CV; using Emgu.Util;
3、在窗体上画一个按钮,然后再按纽的下面写上如下的程序:
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "BMP文件|*.bmp|JPG文件|*.jpg|JPEG文件|*.jpeg|所有文件|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
CvInvoke.cvNamedWindow("打开图片");
IntPtr img = CvInvoke.cvLoadImage(openFileDialog.FileName, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_UNCHANGED);
CvInvoke.cvShowImage("打开图片", img);
this.img = img;
CvInvoke.cvWaitKey(0);
CvInvoke.cvReleaseImage(ref img);
CvInvoke.cvDestroyWindow("打开图片");
}
}
Emgu CV学习之二 保存图片
http://blog.sina.com.cn/s/blog_6174faf60100gg7w.html
我们学会了打开图片,如果要保存图片,也很简单:
创建一根按钮控件,命名为btnSaveImage;然后添加如下代码:
private void btnSaveImage_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "BMP文件|*.bmp|JPG文件|*.jpg|JPEG文件|*.jpeg|所有文件|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
CvInvoke.cvSaveImage(saveFileDialog.FileName, this.img);
}
}
OpenCV学习之三 打开视频文件
http://blog.sina.com.cn/s/blog_6174faf60100gg80.html
创建一根按钮并命名为btnOpenAVI:
双击按钮并添加如下代码:
private void btnOpenAVI_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "AVI文件|*.avi";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
CvInvoke.cvNamedWindow("打开视频");
IntPtr capture=CvInvoke.cvCreateFileCapture(openFileDialog.FileName);
this.video = capture;
IntPtr frame = new IntPtr();
while (true)
{
frame = CvInvoke.cvQueryFrame(capture);
CvInvoke.cvShowImage("打开视频", frame);
//if (!frame) break;
int c = CvInvoke.cvWaitKey(20);
if (c == 13) break;
}
//this.video = capture;
CvInvoke.cvWaitKey(0);
CvInvoke.cvReleaseCapture(ref capture);
CvInvoke.cvDestroyWindow("打开视频");
}
}
OpenCV学习之四:保存视频文件
http://blog.sina.com.cn/s/blog_6174faf60100gg83.html
private void btnSaveAVI_Click(object sender, EventArgs e)
{
IntPtr avi = this.video;
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "BMP文件|*.bmp|JPG文件|*.jpg|JPEG文件|*.jpeg|所有文件|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
// IntPtr videoWriter = CvInvoke.cvCreateVideoWriter(saveFileDialog.FileName, -1, 20, new Emgu.CV.MCvSize(480, 500), 1);
VideoWriter videoWriter = new VideoWriter(saveFileDialog.FileName,20,640,480,true);
IntPtr capture=CvInvoke.cvCreateFileCapture(saveFileDialog.FileName);
IntPtr frame = new IntPtr();
while (true)
{
frame = CvInvoke.cvQueryFrame(capture);
videoWriter.WriteFrame <Bgr,Byte>(frame); }
}
}
这个保存程序还有点问题。
【OpenCV】打开摄像头 保存视频文件(转)
http://blog.sina.com.cn/s/blog_6174faf60100ghng.html
作者:彭军 这个程序首先打开摄像头,然后保存摄像头所拍摄的内容。需要注意的就是在保存视频时编码器的选择,最好用默认的就OK了,就是选压缩程序选择Cinepak Codec by Radius. 压缩质量可以根据自己的需要选择大小。具体程序如下: #include "cv.h" #include "highgui.h" #include "iostream.h" int main() { CvCapture* capture=cvCaptureFromCAM(-1); CvVideoWriter* video=NULL; IplImage* frame=NULL; int n; if(!capture) //如果不能打开摄像头给出警告 { cout<<"Can not open the camera."<<endl; return -1; } else { frame=cvQueryFrame(capture); //首先取得摄像头中的一帧 video=cvCreateVideoWriter("camera.avi",-1,32, cvSize(frame->width,frame->height)); //创建CvVideoWriter对象并分配空间 //保存的文件名为camera.avi,编码要在运行程序时选择,大小就是摄像头视频的大小,帧频率是32 if(video) //如果能创建CvVideoWriter对象则表明成功 { cout<<"VideoWriter has created."<<endl; } cvNamedWindow("Camera Video",1); //新建一个窗口 while(1) { frame=cvQueryFrame(capture); //从CvCapture中获得一帧 if(!frame) { cout<<"Can not get frame from the capture."<<endl; break; } n=cvWriteFrame(video,frame); //判断是否写入成功,如果返回的是1,表示写入成功 cout<<n<<endl; cvShowImage("Camera Video",frame); //显示视频内容的图片 if(cvWaitKey(2)>0) break; //有其他键盘响应,则退出 } cvReleaseVideoWriter(&video); cvReleaseCapture(&capture); cvDestroyWindow("Camera Video"); } return 0; |
直方图均衡化的算法和代码
http://blog.sina.com.cn/s/blog_6174faf60100gra0.html
直方图均衡化算法分为三个步骤,第一步是统计直方图每个灰度级出现的次数,第二步是累计归一化的直方图,第三步是计算新的像素值。
第一步:
for(i=0;i<height;i++){
for(j=0;j<width;j++){
n[s[i][j]]++;
}
}
for(i=0;i<L;i++){
p[i]=n[i]/(width*height);
}
这里,n[i]表示的是灰度级为i的像素的个数,L表示的是最大灰度级,width和height分别表示的是原始图像的宽度和高度,所以,p[i]表示的就是灰度级为i的像素在整幅图像中出现的概率(其实就是p[]这个数组存储的就是这幅图像的归一化之后的直方图)。
第二步:
for(i=0;i<=L;i++){
for(j=0;j<=i;j++){
c[i]+=p[j];
}
}
c[]这个数组存储的就是累计的归一化直方图。
第三步:
max=min=s[0][0];
for(i=0;i<height;i++){
for(j=0;j<width;j++){
if(max<s[i][j]){
max=s[i][j];
}else if(min>s[i][j]){
min=s[i][j];
}
}
}
找出像素的最大值和最小值。
for(i=0;i<height;i++){
for(j=0;j<width;j++){
t[i][j]=c[s[i][j]]*(max-min)+min;
}
}
t[][]就是最终直方图均衡化之后的结果。
{Emgu}{C#}保存图片、视频等的更多相关文章
- Emgu.CV 播放视频
using Emgu.CV; using System; using System.Drawing; using System.Threading; using System.Windows.Form ...
- Emgu CV播放视频
public partial class Form1 : Form { Capture _capture; public Form1() { Initializ ...
- Emgu.CV 播放视频-本地文件/RTSP流
using Emgu.CV; using System; using System.Drawing; using System.Threading; using System.Windows.Form ...
- Emgu 学习(2) 视频文件播放
播放AVI视频文件 static void Main(string[] args) { CvInvoke.NamedWindow("TestVideo", NamedWindowT ...
- 针对监控摄像机(海康、大华等)录像 .h264 文件的流媒体播放设计
监控摄像机(海康.大华等)内部带的录像功能一般录制的是h264文件,这种文件格式简单的把每一帧h264字节数据保存到文件里. 实际使用中,可能需要对特定录像进行反复检测,以训练.改进视频检测算法的准确 ...
- redis基本数据类型及命令
一.key相关命令 redis本质上是key-value数据库.所以key操作适用于redis的任何数据类型缓存. 1.exists key判断是否存在key,存在返回1,不存在返回0 2.del k ...
- 微信小程序(mpvue) wx.openSetting 无法调起设置页面
在开发过程有个需要保存图片/视频到设备相册的业务,so easy~ 巴啦啦撸下来了完整功能, wx.saveVideoToPhotosAlbum 会自动调起用户授权,美滋滋~~ btu.... ...
- nginx的一些知识(一)
第8章 web网站的搭建 curl -Lv 网站地址:查看网站的请求信息和响应信息,并且会将结果输出出来 8.1 web网站的的传输原理过程 会进行DNS的解析 进行客户端和服务端进行三次握手协议 客 ...
- 基于Emgu CV+百度人脸识别,实现视频动态 人脸抓取与识别
背景 目前AI 处于风口浪尖,作为 公司的CTO,也作为自己的技术专研,开始了AI之旅,在朋友圈中也咨询 一些大牛对于AI 机器学习框架的看法,目前自己的研究方向主要开源的 AI 库,如:Emgu C ...
随机推荐
- android AVD启动失败原因之一
在mac上安装好Android SDK.AVD及相关的组件之后,手动创建了一个安卓模拟器后,通过actions启动,会弹出一个提示窗口,然后就闪退,也没有报错什么的,在网上搜了半天AVD启动失败的问题 ...
- JXLS导出Excel(模板导出)
1.导包 在pom.xml中加入依赖如下: <dependency> <groupId>org.jxls</groupId> <artifactId>j ...
- HDU 4750 Count The Pairs ★(图+并查集+树状数组)
题意 给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值.Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, ...
- QT中Qtableview视图表格中点击表头进行排序
用QT写了一个小工具,主要是对Excel中大量的数据进行计算和显示. 写了有一段时间,然后断断续续的做一些修改和完善. 因为要显示的数据有多列,很自然的会想到要能够对显示的数据进行排序.如果直接操作m ...
- hdu2426
题解: KM模板题 如果n>m,输出-1 如果a[match[i]][i]==-1输出-1 负的边不用考虑 初始都赋值为-1 代码: #include<cstdio> #includ ...
- hdu4453
题解: splay模板 删除,翻转等等 代码: #include<cstdio> #include<cstring> #include<cmath> #includ ...
- LeetCode OJ:H-Index(H指数)
Given an array of citations (each citation is a non-negative integer) of a researcher, write a funct ...
- pig 自定义udf中读取hdfs 文件
最近几天,在研究怎么样把日志中的IP地址转化成具体省份城市. 希望写一个pig udf IP数据库采用的纯真IP数据库文件qqwry.dat,可以从http://www.cz88.net/下载. 这里 ...
- 浅谈js异步
大家都知道,js是一个单线程的语言(只有一个线程来执行js函数),所以如果某一个函数执行任务耗时比较长的话,就会造成阻塞,使得后续任务一直处于等待状态. 一.阻塞示例 function f1(){ ; ...
- GPU编程自学1 —— 引言
深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...