切り取りと結合(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;
}