现在的位置: 首页 > 综合 > 正文

C# 中使用OPenCV(Emgu)心得

2013年02月20日 ⁄ 综合 ⁄ 共 15704字 ⁄ 字号 评论关闭
文章目录

關於VS2010+openCV2.2在win7下 有webcam bug

  • 本人是研究生 目前在做機器人的SLAM 有幸使用VS2010

    之前裝好opencv 遇到一個問題就是除了webcam沒有畫面外 其他的code 順利運行

    這幾天找很久 卻發現在台灣只能在網路上找答案 卻很少人PO指導文跟問題經驗分享

    找的答案與教學文大都是從中國找到  所以我在這裡提供一個經驗給大家 

    PS.最好下載OpenCV-2.2.0-win.zip 
    (需要編譯的) 不是
    OpenCV-2.2.0-win32-vs2010.exe

     win7與openCV 2.2 有一個bug  編譯前要修改一個檔案

    $(安裝OpenCV目錄)\modules\highgui\src\precomp.hpp

    再找到:

    #if !defined WIN32 && !defined _WIN32

    #include "cvconfig.h"
    #else
    void  FillBitmapInfo( BITMAPINFO* bmi, int
    width, int height, int
    bpp,
    int origin );
    #endif


    取代成:

    #include "cvconfig.h"

    #if defined WIN32 || defined _WIN32
    void  FillBitmapInfo( BITMAPINFO* bmi, int
    width, int height, int
    bpp,
    int origin );
    #endif

    這樣就可以照官網編譯成功 並且webcam可以擷取畫面成功

     

所有回覆

  • 2011年5月15日 上午 10:48

     

     

    您好:

    我是準備要做機器人相關 SLAM技術

    要在windows底下開發APP 所以採用VS2010 + opencv + EnguCV

    可是最主要webcam 畫面卻一直跑不出來

    實驗環境

    OS:windows 7 32 bit

    CPU:AMD Athlon 64x2 3800+

    RAM:DDR 400 1G

    WebCam: LifeCam studio

    IDE:VS2010

    首先是先測試OpenCV + C++

    官網提供的測試範例 基本上都可以執行 所以在設定opencv應該是沒有問題

    不過要測試別人寫的webcam

     

    #include "stdafx.h"

    #include "cv.h"

    #include "highgui.h"

    int _tmain(int argc, _TCHAR* argv[])

    {
     
     IplImage* pImg; //聲明IplImage指針

            cvNamedWindow( "Camera", 1 );
     

            CvCapture *capture;
     int c; 

        
     capture = cvCaptureFromCAM(0);
     if(!capture)

    return -1;

    else

            printf("Camera is OK! \n");


    while(true){
     
    if(cvGrabFrame(capture)){

    pImg = cvRetrieveFrame(capture);

    cvShowImage( "Camera", pImg );

    }


    //等待ESC按鍵按下則結束

    if(cvWaitKey(10) == 27)

    break;

    } // end of while 
      cvWaitKey(0);

           cvDestroyWindow( "Camera" );//銷毀視窗

    cvReleaseCapture( &capture );  

    return 0;

    }

    卻會一直出現灰色 畫面顯示不出來 我換用Ubuntu+Qtcreator 卻沒問題 成功有畫面

    到底是出在OS?? VS2010??  起初以為是webcam支援性問題 因為可以在其他OS下執行就排除

     

    最後在試EnguCV+C# 也是一樣...範例基本上都沒問題可以執行 就是關於webcam功能都無法顯示畫面

     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using Emgu.CV;

    using Emgu.CV.UI;

    using Emgu.CV.Structure;

    using System.Drawing;

    using System.Windows.Forms;

    namespace test02

    {

        class Program

        {

            static void Main(string[] args)

            {

                ImageViewer viewer = new ImageViewer(); //create an image viewer

                Capture capture = new Capture(); //create a camera captue

                Application.Idle += new EventHandler(delegate(object sender, EventArgs e)

                {  //run this until application closed (close button click on image viewer)

                    viewer.Image = capture.QueryFrame(); //draw the image obtained from camera

                });

                viewer.ShowDialog(); //show the image viewer

            }

        }

    }

    PS.在執行上面code webcam上的燈有亮 卻沒畫面

     

 

 

 

http://blog.csdn.net/plutus_lee/article/details/7788234

 

2011/05/17 在 Visual Studio 2010 使用 OpenCV 對於 WebCam 有問題的話,請參考以下連結

http://social.msdn.microsoft.com/Forums/zh-TW/230/thread/d1647ae6-7f61-453e-818a-2fa4f52592bb

 

一、簡介

以前研究所的時候,有使用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加入工具箱中,加入後會出現 ImageBoxHistogramCtrl

 

 

5. 到此,已經將要撰寫OpenCV的工作完成了。開始撰寫程式碼,在這裡示範兩個範例,第一個是開啟並顯示 WebCam
畫面。

5.1 先在Form上拉兩個控制項,分別是Button ( Name : captureButton )與 ImageBox ( Name : captureImageBox )

 

5.2 撰寫以下程式碼

01
using
System;
02
using
System.Collections.Generic;
03
using
System.ComponentModel;
04
using
System.Data;
05
using
System.Drawing;
06
using
System.Linq;
07
using
System.Text;
08
using
System.Windows.Forms;
09
10 // 要引用的類別
11 using Emgu.CV;
12 using Emgu.CV.Structure;
13 using Emgu.Util;
14 using System.Threading;

15
16 namespace MyOpenCV
17 {
18     public partial
class Form2 :Form
19     {
20         public Form2()
21         {
22             InitializeComponent();
23         }
24
25         private Capture_capture;
26         private
bool_captureInProgress;
27
28         private
voidProcessFrame(object sender, EventArgs arg)
29         {
30             Image<Bgr,Byte> frame = _capture.QueryFrame();  
31             captureImageBox.Image= frame;
32         }
33
34         private
voidcaptureButton_Click(object sender, EventArgs e)
35         {
36             if capture
is not created, create it now
49
50             if (_capture!=
null)
51             {
52                 if(_captureInProgress)
53                 {  //stop thecapture

54                     Application.Idle-=
new
EventHandler(ProcessFrame);
55                     captureButton.Text=
"Start Capture"
;
56                 }
57                 else
58                 {
59                     //start thecapture

60                     captureButton.Text=
"Stop"
;
61                     Application.Idle+=
new
EventHandler(ProcessFrame);
62                 }
63
64                 _captureInProgress= !_captureInProgress;
65             }
66         }
67     }
68 }

 

5.3 執行結果,請注意喔,以下顯示的是 Webcam 即時視訊,不是影像喔

 

6. 第二個範例,我們將上一個範例,加上灰階、Canny處理

讓大家了解 OpenCV 的強大,而這動作,只需要多拉兩個ImageBox在加上幾行程式就可以了喔,真是太讚了,難怪很多學生想畢業,都用OpenCV

6.1 在上一個範例中,在多拉兩個 ImageBox,Name 分別為grayscaleImageBox、cannyImageBox

 

6.2 將上一個範例,加上四行程式碼就可以達成將Webcam視訊灰階以及Canny

 

01
using
System;
02
using
System.Collections.Generic;
03
using
System.ComponentModel;
04
using
System.Data;
05
using
System.Drawing;
06
using
System.Linq;
07
using
System.Text;
08
using
System.Windows.Forms;
09
10 // 要引用的類別
11 using Emgu.CV;
12 using Emgu.CV.Structure;
13 using Emgu.Util;
14 using System.Threading;

15
16 namespace MyOpenCV
17 {
18     public partial
class Form2 :Form
19     {
20         public Form2()
21         {
22             InitializeComponent();
23         }
24
25         private Capture_capture;
26         private
bool_captureInProgress;
27
28         private
voidProcessFrame(object sender, EventArgs arg)
29         {
30             Image<Bgr,Byte> frame = _capture.QueryFrame();  
31             captureImageBox.Image= frame;
32
33             //
請再加上以下四行程式碼
34             Image<Gray,Byte> grayFrame = frame.Convert<Gray, Byte>();
35             Image<Gray,Byte> cannyFrame = grayFrame.Canny(new Gray(100),
new Gray(60));
36             grayscaleImageBox.Image= grayFrame;
37             cannyImageBox.Image= cannyFrame;
38         }
39
40         private
voidcaptureButton_Click(object sender, EventArgs e)
41         {
42             if capture
is not created, create it now
55
56             if (_capture!=
null)
57             {
58                 if(_captureInProgress)
59                 {  //stop thecapture

60                     Application.Idle-=
new
EventHandler(ProcessFrame);
61                     captureButton.Text=
"Start Capture"
;
62                 }
63                 else
64                 {
65                     //start thecapture

66                     captureButton.Text=
"Stop"
;
67                     Application.Idle+=
new
EventHandler(ProcessFrame);
68                 }
69
70                 _captureInProgress= !_captureInProgress;
71             }
72         }
73     }
74 }

 

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、在窗体上画一个按钮,然后再按纽的下面写上如下的程序:

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("打开图片");
            }
        }

 

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;
             

抱歉!评论已关闭.