0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OpenCV 切り貼りと連結

Posted at

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


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?