物理のバス停 by salt22g

とある物理学見習いの備忘録。

二つのファイルに保存されている画像を合成する

python version

import numpy as np
import cv2
import os
import glob
import sys
import re

args = sys.argv
filename1 = args[1]
filename2 = args[2]
outname = args[3]


if __name__ == "__main__":


    new_dir = outname + "/"
    os.makedirs(new_dir, exist_ok=True)

    files1 = glob.glob(filename1 + "/*.png")
    files1.sort()

    files2 = glob.glob(filename2 + "/*.png")
    files2.sort()

    i = 0
    for file1, file2 in zip (files1, files2):
        img1 = cv2.imread(file1)
        img2 = cv2.imread(file2)
        merge_img = cv2.add(img1, img2)
        cv2.imwrite(new_dir + "{:08}.png".format(i), merge_img)
        i += 1

C++ vesion

前半部分はこの方のコードを拝借。
Python built-in zip() method implemented in C++ · GitHub

#include "opencv2/opencv.hpp"

#include "TStyle.h"
#include "TFile.h"
#include "TTree.h"

#include "TMath.h"
#include "TRandom.h"

#include <stdio.h>
#include <stdlib.h>
#include <string>

#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>
#include <random>
#include <vector>

#include <sys/stat.h>
#include <glob.h>


template<typename T>
class Zip
{
    
public:
    
  typedef std::vector<T> container_t;
    
  template<typename... Args>
  Zip(const T& head, const Args&... args)
    : items_(head.size()),
      min_(head.size())
  {
    zip_(head, args...);
  }
    
  inline operator container_t() const
  {
    return items_;
  }
    
  inline container_t operator()() const
  {
    return items_;
  }
    
private:
    
  template<typename... Args>
  void zip_(const T& head, const Args&... tail)
  {
    // If the current item's size is less than
    // the one stored in min_, reset the min_
    // variable to the item's size
    if (head.size() < min_) min_ = head.size();
        
    for (std::size_t i = 0; i < min_; ++i)
      {
	// Use begin iterator and advance it instead
	// of using the subscript operator adds support
	// for lists. std::advance has constant complexity
	// for STL containers whose iterators are
	// RandomAccessIterators (e.g. vector or deque)
	typename T::const_iterator itr = head.begin();
            
	std::advance(itr, i);
            
	items_[i].push_back(*itr);
      }
        
    // Recursive call to zip_(T, Args...)
    // while the expansion of tail... is not empty
    // else calls the overload with no parameters
    return zip_(tail...);
  }

  inline void zip_()
  {
    // If min_ has shrunk since the
    // constructor call
    items_.resize(min_);
  }

  /*! Holds the items for iterating. */
  container_t items_;
    
  /*! The minimum number of values held by all items */
  std::size_t min_;
    
};

template<typename T, typename... Args>
typename Zip<T>::container_t zip(const T& head, const Args&... tail)
{
  return Zip<T>(head, tail...);
}


std::vector<std::string> get_file_path(std::string input_dir, std::string wildcard){
  glob_t globbuf;
  std::vector<std::string> files;
  glob((input_dir + wildcard).c_str(), 0, NULL, &globbuf);
  for (int i = 0; i < globbuf.gl_pathc; i++){
    files.push_back(globbuf.gl_pathv[i]);
  }
  globfree(&globbuf);
  return files;
}


int main(int argc, char *argv[]){

  std::string input_dir1 = argv[1];
  std::string input_dir2 = argv[2];
  std::string output_dir = argv[3];
  
  std::string png = "/*.png";

  mkdir(Form("result_image/%s", output_dir.c_str()), S_IRWXU | S_IRWXG | S_IRWXO);

  std::vector<std::string> events1 = get_file_path(input_dir1, png);
  std::vector<std::string> events2 = get_file_path(input_dir2, png);
  std::sort(events1.begin(), events1.end());
  std::sort(events2.begin(), events2.end());

  std::string f;
  int i = 0;

  for (auto j : zip(events1, events2)){
    
    std::cout << j[0] << std::endl;
    std::cout << j[1] << std::endl;
    cv::Mat img1 = cv::imread(j[0], cv::IMREAD_COLOR);
    cv::Mat img2 = cv::imread(j[1], cv::IMREAD_COLOR);
    
    cv::Mat out_img;
    cv::add(img1, img2, out_img);
    
    cv::imwrite(Form("result_image/%s/%08d.png",output_dir.c_str(), i), out_img);
    i += 1;
  }
}