Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

OpenCV 切り貼りと連結

More than 3 years have passed since last update.

切り取りと結合(msvc2015,openvc3.1)
同じサイズの複数枚画像から指定部分を切り取り、それらを一枚の画像に合成します。

Measure.cpp
//  : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"

#include <stdio.h>
#include <direct.h>
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <filesystem>


#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

#include "getopt.h"

using namespace std;


int main1(int argc, char* argv[]);
int main2(int argc, char* argv[]);
int main3(int argc, char* argv[]);

int usage(void)
{
    cout << "[usege] flmeasure <dirname>" << endl;
    cout << endl;
    cout << "OpenCV version: " << CV_VERSION << endl;
    return 1;
}

// メイン
int main(int argc, char* argv[])
{
    //return main1(argc, argv);
    //return main2(argc, argv);
    return main3(argc, argv);
}
//
//
// 
int main1(int argc, char* argv[])
{
    return main2(argc, argv);

    const int y = 1710;
    const int h = 80;
    double angle = 0.4;
    double scale = 1.0;


    cv::Mat src_img = cv::imread("C:\\MyData\\CUD099\\0706-4\\DSC00285.JPG");
    cv::namedWindow("Img", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("Img2", cv::WINDOW_AUTOSIZE);
    // cv::namedWindow("Img3", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("combined", cv::WINDOW_AUTOSIZE);
    //
    cv::Point2d center(0, y);       // 回転中心を指定
    const cv::Mat affine_matrix = cv::getRotationMatrix2D(center, angle, scale);
    //
    cv::warpAffine(src_img, src_img, affine_matrix, src_img.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(255));

    cv::imshow("Img", src_img);

    cv::Mat img2(src_img, cv::Rect(0, y - h / 2, 3007, h));     // 切り取り
    cv::imshow("Img2", img2);

    cv::Mat combined(cv::Size(src_img.size().width, 1000), CV_8UC3);
    cv::Mat roi(combined, cv::Rect(0, 100, 3007, h));
    img2.copyTo(roi);
    cv::imshow("combined", combined);

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

int main2(int argc, char* argv[])
{
    cout << "FLMeasure 1.00 ((Fluid Level Measure))" << endl;

    // 1) 画像ファイルのあるディレクトリを決定する
    char defaultpath[_MAX_PATH] = "C:\\MyData\\CUD099\\0706-4";
    char pathname[_MAX_PATH];
    if (argc > 1) {
        strcpy_s(pathname, argv[1]);
    }
    else {
        strcpy_s(pathname, defaultpath);
    }

    // 2) ディレクトリ内のすべてのファイルのフルパスをlistに格納する。
    list<string> flist;
    std::tr2::sys::path p(pathname);

    for_each(std::tr2::sys::directory_iterator(p),
        std::tr2::sys::directory_iterator(),
        [&flist](const std::tr2::sys::path& p) {
        if (std::tr2::sys::is_regular_file(p)) {
            string s = p.string();
            flist.push_back(s);
        }
    });

    // 3) 画像を読み出し有効ならvectorに格納する。
    vector<cv::Mat> src_img;

    for (auto itn = flist.begin(); itn != flist.end(); itn++)
    {
        cv::Mat img = cv::imread(itn->data());
        if (img.empty()) {
            continue;
        }
        cout << itn->data() << endl;
        src_img.push_back(img);
    }
    if(src_img.empty()){
        return usage();
    }

    // 短冊状に切り出し、結合する。

    const int y = 1710;
    const int h = 40;
    double angle = 0.4;
    double scale = 1.0;

    // 結合結果保存用領域
    cv::Mat combined(cv::Size(src_img[0].size().width, src_img.size()*h), CV_8UC3);

    cv::Rect rot_rect;
    for (auto it = src_img.begin(); it != src_img.end(); it++)
    {

        //      cv::Point2d center(0, y);       // 回転中心を指定
        //      const cv::Mat affine_matrix = cv::getRotationMatrix2D(center, angle, scale);
        //      cv::warpAffine(it->data(), it->data(), affine_matrix, it->data().src_img.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(255));

        cv::Mat img2((*it), cv::Rect(0, y - h / 2, 3007, h));       // 切り取り
        {


        }
        rot_rect.width = img2.cols;
        rot_rect.height = img2.rows;
        cv::Mat roi(combined, rot_rect);
        img2.copyTo(roi);

        rot_rect.y += img2.rows;

    }


    cv::imshow("combined", combined);
    string outdir = p.string() + "\\Result\\";
    _mkdir(outdir.c_str());
    string outfile = outdir +"combined.jpg";
    cv::imwrite(outfile, combined);

    cv::waitKey(0);

    return 0;
}



///////////////////////////////////////////////////////////////////////////////
// 
////////////////////////////////////////////////////////////////////////////////

int usage_main3()
{
    cout << "FLMesure <option> dirname " << endl;
    cout << " -Axxx : pointA.y 左上隅からの切り取り中心までの長さ" << endl;
    cout << " -Txxx : threshold (0 to 255" << endl;
    cout << endl;
    cout << "sample : flmesute -A1800 -T150 d:\0706-4" << endl;
    return 1;
}

int main3(int argc, char* argv[])
{
    cout << "FLMeasure 1.04 (Fluid Level Measure m3)" << endl;

    // パラメータ
    cv::Point ptA(0,1710);          // 左の点(切り出し画像中心)
    cv::Point ptB(0,1710);          // 右の点(切り出し画像中心)
    int hight = 40;                 // 切り出し幅
    int threshold = 150;            // 閾値

                                //
    // getoptを使用する。
    //  optarg          caseブロックの中で参照する。オプションに続く次のテキスト
    //  optind
    //  opterr          0でエラー表示抑制
    //  optopt          
    int optres;         
    while ((optres = getopt(argc, argv, "A:B:H:T:")) != -1) {
        switch (optres){
        case 'A':
            ptA.y = atoi(optarg);
            break;
        case 'B':break;
        case 'H':break;
        case 'T':
            threshold = atoi(optarg);
            break;
        default:
            return usage_main3();
        }
    }
    // 1) オプション以外の引数(ディレクトリ指定)
    char defaultpath[_MAX_PATH] = "C:\\MyData\\CUD099\\0706-4";
    char pathname[_MAX_PATH];
    strcpy_s(pathname, defaultpath);
    for(int i=optind; i<argc; i++){
        strcpy_s(pathname, argv[i]);
        break;
    }
    cout << "pointA.y= " << ptA.y << endl;
    cout << "threshold= " << threshold << endl;


    // 2) ディレクトリ内のすべてのファイルのフルパスをlistに格納する。
    list<string> flist;
    std::tr2::sys::path p(pathname);

    for_each(std::tr2::sys::directory_iterator(p),
        std::tr2::sys::directory_iterator(),
        [&flist](const std::tr2::sys::path& p) {
        if (std::tr2::sys::is_regular_file(p)) {
            string s = p.string();
            flist.push_back(s);
        }
    });
    // 


    // 3) 画像を読み出し有効ならvector<cv::Mat>に格納する。
    vector<cv::Mat> src_img;

    for (auto itn = flist.begin(); itn != flist.end(); itn++)
    {
        cv::Mat img = cv::imread(itn->data());
        if (img.empty()) {
            continue;
        }
        cout << itn->data() << endl;
        src_img.push_back(img);
    }
    if (src_img.empty()) {
        return usage();         // 画像なし
    }




    string outdir = p.string() + "\\Result\\";
    _mkdir(outdir.c_str());
    string outfile = outdir + "combined.jpg";
    string outcsv = outdir + "result.csv";

    ofstream ofs(outcsv);

    // 短冊状に切り出し、結合する。

    const int y = ptA.y;
    const int h = hight;
    double angle = 0.4;
    double scale = 1.0;

    // 結合結果保存用領域

    cv::Mat combined(cv::Size(src_img[0].size().width, src_img.size()*h), CV_8UC3);

    vector<cv::Mat> v1s;


    cv::Rect rot_rect;
    for (auto it = src_img.begin(); it != src_img.end(); it++)
    {

        //      cv::Point2d center(0, y);       // 回転中心を指定
        //      const cv::Mat affine_matrix = cv::getRotationMatrix2D(center, angle, scale);
        //      cv::warpAffine(it->data(), it->data(), affine_matrix, it->data().src_img.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(255));

        cv::Mat img2((*it), cv::Rect(0, y - h / 2, src_img[0].size().width, h));        // 切り取り
        cv::Mat gray_img;
        cv::cvtColor(img2, gray_img, cv::COLOR_RGB2GRAY);           // グレイスケール
        cv::Mat v1;
        cv::reduce(gray_img, v1, 0, CV_REDUCE_AVG);                 // 1行に縮小平均
        v1s.push_back(v1);
        {


        }
        rot_rect.width = img2.cols;
        rot_rect.height = img2.rows;
        cv::Mat roi(combined, rot_rect);
        img2.copyTo(roi);

        rot_rect.y += img2.rows;

    }

    cv::Mat iout;
    cv::vconcat(v1s, iout);             // 
    cv::Mat ioutt = iout.t();


    ofs << cv::format(ioutt, cv::Formatter::FMT_CSV);   // CSV形式で出力する。


    cv::imshow("iout", iout);


    //
    // ----------------------------------------------------------
    //
    ofs << endl << "結果" << " (閾値= " << threshold << " )" << endl;
    ofs << "No., 画素位置" << endl;
    for (int x = 0; x < ioutt.cols; x++) {
        ofs << x << ",";
        for (int y = 0; y < ioutt.rows; y++) {
            if (iout.at<unsigned char>(x, y) < threshold)
            {
                ofs << y << endl;
                break;
            }
        }
    }

//  for (int i = 0; i<iout.rows, i++){
//      for (int j = 0; j < iout.cols; j++) {
//          ofs << iout<unsigned char>(i, j) << ;
//
//      }
//  }


    // hconcat

#if 0
    cv::Mat mat = (*v1s.begin());
    for (auto it = mat.begin<unsigned char>(); it != mat.end<unsigned char>(); it++)
    {
        ofs << (int)(*it) << endl;
    }
#endif


    cv::imshow("combined", combined);
    cv::imwrite(outfile, combined);

    cv::waitKey(0);

    return 0;
}


omhw
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away