天天看點

Opencv——批量處理同一檔案夾下的圖檔(解決savedfilename = dest + filenames[i].substr(len)問題)

文章目錄

  • ​​前言​​
  • ​​一、完整代碼​​
  • ​​二、實作效果​​

前言

第一份代碼實作了批量修改同一檔案夾下圖檔的尺寸,有其他需求時僅需修改處理部分的代碼以及檔案夾路徑。

第二份代碼實作了批量截取同一檔案夾下每張圖檔的ROI區域作為結果儲存,注意截取後按下enter鍵才會跳到下一張圖檔,同時若是對已經截取的不滿意隻要不按下enter鍵都是可以重新選擇的,這都得益于selectROI函數。

參考了文章:

​​​opencv——批量處理圖檔并儲存​​

但是編譯時發現了問題,debug發現是下面一行代碼出了問題。

savedfilename = dest + filenames[i].substr(55);      

報錯:

[[noreturn]] static void _Xlen()

經過百度,發現代碼中的55意味着path的字元串長度。修改代碼為

int len = path.length();
savedfilename = dest + filenames[i].substr(len);      

問題解決。

一、完整代碼

代碼1:

#include <opencv2/opencv.hpp>
#include "opencv2/features2d.hpp"
#include <vector>
#include <algorithm>
#include <iostream>
#include "windows.h"
#include <stdio.h>
#include <time.h>
#include <math.h>  
#include <fstream>
#define WINDOW_NAME "【程式視窗】"      
using namespace cv;
using namespace std;
int main()
{
  cv::String path = "D:/opencv_picture_test/視覺項目新/";        //待處理圖檔檔案夾位址
  cv::String dest = "D:/opencv_picture_test/視覺項目resize後的圖檔夾/測試圖檔夾/";    //處理後圖檔的儲存位址
  cout << "擷取位址成功"<< endl;
  cv::String savedfilename;
  std::vector<cv::String> filenames;
  int len = path.length();
  cv::Mat srcImg, dstImg;
  cv::glob(path, filenames);                 //opencv裡面用來讀取指定路徑下檔案名的一個很好用的函數
  for (int i = 0; i < filenames.size(); i++) {
    srcImg = cv::imread(filenames[i]);
    //*************************對圖檔的處理部分***************************/
    //這裡我們批量修改圖檔的大小
    resize(srcImg, dstImg,Size(600,450));
    //********************************************************************/
    savedfilename = dest + filenames[i].substr(len);
    std::cout << savedfilename << std::endl;
    cv::imwrite(savedfilename, dstImg);
    cout << "第" << i << "張完成" << endl;
  }
  waitKey(0);
  return 0;
}      

代碼2:

#include <opencv2/opencv.hpp>
#include "opencv2/features2d.hpp"
#include <vector>
#include <algorithm>
#include <iostream>
#include "windows.h"
#include <stdio.h>
#include <time.h>
#include <math.h>  
#include <fstream>
#define WINDOW_NAME "【程式視窗】"      
using namespace cv;
using namespace std;
int main()
{
  //改變控制台字型顔色
  system("color 02");
  cv::String path = "D:/opencv_picture_test/視覺項目resize後的圖檔夾/測試圖檔夾/";        //待處理圖檔檔案夾位址
  cv::String dest = "D:/opencv_picture_test/視覺項目resize後的圖檔夾/模闆圖檔夾/";    //處理後圖檔的儲存位址
  cout << "擷取位址成功" << endl;
  cv::String savedfilename;
  std::vector<cv::String> filenames;
  int len = path.length();
  cv::Mat srcImg, dstImg;
  cv::glob(path, filenames);                 //opencv裡面用來讀取指定路徑下檔案名的一個很好用的函數
  for (int i = 0; i < filenames.size(); i++) {
    srcImg = cv::imread(filenames[i]);
    //*************************對圖檔的處理部分***************************/
    //這裡我們批量選擇原圖中的某塊ROI區域作為結果儲存
    Rect2d r;
    r = selectROI(srcImg, true);  //選擇一個矩形roi區域
    dstImg = srcImg(r);     //此區域為模闆區域
    destroyAllWindows();
    //********************************************************************/
    savedfilename = dest + filenames[i].substr(len);
    std::cout << savedfilename << std::endl;
    cv::imwrite(savedfilename, dstImg);
    cout << "第" << i << "張完成" << endl;
    waitKey(30);
  }
  return 0;
}      

有些多餘的頭檔案可以不添加。

二、實作效果