• 工具

採取QT5.6.1+opencv2.4.9
本文以實現將手寫數字圖片轉化為csv檔案列子

  • 實現思路:
    -1.將手寫數字以分類在不同資料夾中(0-9)如下圖所示:這裡寫圖片描述
    -2.將所有圖片的路徑載入到txt檔案中dir /b/s *.png > image.txt;生成的txt檔案如下圖:這裡寫圖片描述
    -3.創立QFile csvFile(FILE_PATH),FILE_PATH為最終生產的csv檔案的路徑位置;
    開啟:csvFile.open(QIODevice::ReadWrite)
    這裡需要用ifstream進行檔案流讀取
  ifstream getNamelist(picTXTtoute);//picTXTtoute:為image.txt的位置(string)
  while(getline(getNamelist,ImgName))//讀入txt的一行到ImgName,從而獲取了第一幅圖片的路徑,反覆讀取,則實現了對圖片的批量處理。

-4我們以每類圖片所在資料夾的名字作為其標籤(label),為了使生產的csv檔案為(標籤+畫素值 畫素值 畫素值….)的結構我們現在需要獲取每個ImgName的第56位字元,即(0-9),我們可以用以下句法實現

  QString Dirroute =QString::fromStdString(ImgName);//為了得到標籤(所以對與資料夾和圖片的命名要有規律)
  QString Midroute = Dirroute.mid(56,1);//標籤位置
  Midroute.append(",");//為轉換為csv檔案加“,”只要不是圖片的最後一個畫素那都是(畫素值,)結構,最後一個畫素那就是(畫素值\n)結構;

注意在將(畫素值,)(畫素值\n)寫入csvFile中的時候,我們需要Midroute轉換為哦ascii碼,在QT中用下面的語句實現

csvFile.write(Midroute.toLatin1());//這個是QFile::write()型別必須的,QString轉換為ascii的句法。

至此我們已經將第一幅圖片的標籤寫入了csv檔案中,如下圖綠色框選的位置
這裡寫圖片描述
-5我們在進行圖片畫素的寫入之前,我們需要知道幾個小知識點,第一:我們的圖片是三通道的,即一個畫素點需要用三個畫素值表示,在我們得到圖片的rows和cols的之後,我們要將其儲存的1*N的矩陣中,這個N不是rows*cols 而是rows*cols*3;
第二:本文用at去訪問畫素點,所以我們要提前知道Mat的資料型別,這裡我們的圖片Mat型別是uchar,uchar c = image.at(i,j);第二:用at訪問的時候,image.at(i,j)實際訪問的是(j,i)畫素點的值;第三:為了在讀取後的畫素值後面加上“,”或者“\n”我們需要用到下面的知識點:

QString i = "iTest";           // current file's number  
QString total = "totalTest";       // number of files to process  
QString fileName = "fileNameTest";    // current file's name  

QString status = QString("Processing file %1 of %2: %3")  
                .arg(i).arg(total).arg(fileName);  

記住最後QString要抓還為ascii才能寫入csv;
-6最後,要用csvFile.close();結束csv檔案操作

下面上程式碼:
.cpp

void ImagePreprocessing::writeImageToCSV(string picTXTtoute)
{
    QString str;
    QFile csvFile(FILE_PATH);//建立QFile物件 csvFile,File_PATH為csvFile檔案儲存的路徑及型別
    Mat inputImage;//接受從txt檔案讀入路徑的圖片
    string ImgName; //接受從txt檔案中讀入圖片的路徑
    int rows,cols;
    ifstream getNamelist(picTXTtoute);//讀取儲存了圖片路徑和格式的txt文件
    if(csvFile.open(QIODevice::ReadWrite))//開啟檔案,進行操作
    {
        while(getline(getNamelist,ImgName))//讀入一行,\n為結束符
        {
            QString Dirroute =QString::fromStdString(ImgName);//為了得到標籤(所以對與資料夾和圖片的命名要有規律)
            QString Midroute = Dirroute.mid(56,1);//標籤位置
            Midroute.append(",");//為轉換為csv檔案加“,”

            csvFile.write(Midroute.toLatin1());//這個是QFile::write()型別必須的,QString轉換為ascii的句法。寫在沒個圖片的前面,作為標籤號
            //            qDebug() << Midroute;
            //        cout<< ImgName <<endl; //路徑輸出
            inputImage = imread(ImgName);
            if(!inputImage.data)//異常退出
                return;
            rows = inputImage.rows;
            cols = inputImage.cols;
            int flagNum = rows * cols * 3;
            int countNum = 0;
            //            cout << flagNum << endl;
            for(int i = 0; i <rows; i++)//把衣服圖片轉換為N*1的矩陣。
            {
                for(int j = 0; j< cols * 3; j++)
                {
                    countNum++;
                    uchar c = inputImage.at<uchar>(i,j);//用at操作,事前就要知道Mat中資料儲存型別,uchar,flaot,或者其他。
                    if(countNum == flagNum)
                    {
                        str = QString("%1\n").arg(c);//最後一個畫素,在後面新增\n作為行結束符號
                        //                        qDebug() << str;
                    }
                    else
                        str = QString("%1,").arg(c);//非最後一個畫素值,則用逗號,隔開資料。
                    csvFile.write(str.toLatin1());//csvFile。write()遇到\n則會換行進行寫,遇到的是“,”則繼續在逗號後面寫入資料
                    //                                   qDebug() << str;
                }
            }
        }
    }
    csvFile.close();//寫完以後記住要關閉csv檔案,正常結束
    return;
}
.