2016-11-24 59 views
0

我正在嘗試遍歷目錄並讀取裏面的圖像,同時允許跳過每個第n個文件。在移出界限之前停止directory_iterator

我的代碼目前看起來是這樣的:

// Count number of files in directory and reserve memory (take skipped slices into account) 
std::experimental::filesystem::directory_iterator it_begin{path}; 
int count = count_if(it_begin, std::experimental::filesystem::directory_iterator(), [](const std::experimental::filesystem::directory_entry & d) {return !is_directory(d.path());}); 
auto maxCount = count - (count % (1 + skipSlices)); 
m_imageStack.reserve(maxCount); 

// Read image stack and check for validity 
int n = 0; 
for (std::experimental::filesystem::v1::directory_iterator it(path); it != std::experimental::filesystem::v1::directory_iterator(); std::advance(it, 1 + skipSlices)) 
{ 
    std::string filename{std::experimental::filesystem::v1::path(*it).string()}; 
    cv::Mat image = cv::imread(filename); 
    m_imageStack.push_back(image); 

    n = n + 1 + skipSlices; 
    if (n == maxCount) break; 
} 

如果skipSlices = 1,我只是想讀每2圖像等。對於不動出界,我加了一箇中斷條件的for循環中。我現在的解決方案是非常糟糕的,我想擺脫休息,而是在for循環中使用更正確的停止條件。然而,我無法找到一種方法來告訴迭代器在超前前停止。任何想法如何解決這個問題?

回答

1

只需編寫一個advance版本,該版本將採取限制。

namespace detail { 
    template<class It, class Dist> 
    void advance_with_limit_impl(It& it, It end, Dist n, std::random_access_iterator_tag) { 
     if(n > 0) it += std::min(end - it, n); 
     else it += std::max(end - it, n); 
    } 

    template<class It, class Dist> 
    void advance_with_limit_impl(It& it, It end, Dist n, std::bidirectional_iterator_tag) { 
     if(n > 0) { while(n != 0 && it != end) { --n; ++it; } } 
     else { while (n != 0 && it != end) { ++n; --it; } } 
    } 

    template<class It, class Dist> 
    void advance_with_limit_impl(It& it, It end, Dist n, std::input_iterator_tag) { 
     while(n != 0 && it != end) { --n; ++it; } 
    } 
} 

template<class It> 
void advance_with_limit(It& it, It end, 
         typename std::iterator_traits<It>::difference_type n) { 
    detail::advance_with_limit_impl(it, end, n, 
           typename std::iterator_traits<It>::iterator_category()); 
} 

然後只使用advance_with_limit(it, {}, 1 + skipSlices)