Siv3Dとopencvの併用について
keni  2016/09/21(Wed) 08:14
Siv3D(August2016v2) を選択してプロジェクトを作成した際に、
opencvの機能を使用しようとするとビルド時にエラーが出てしまいます。

Siv3D(August2016v2) を選択してプロジェクトを作成した場合、
imshowなどのウィンドウを生成してしまうようなコードは使用できないのでしょうか?
それとも、何か別の問題があるのでしょうか?

下記にエラーとソースコードを記載致します。


【エラー】
エラー:LNK2019 未解決の外部シンボル "void __cdecl Main(void)" (?Main@@YAXXZ) が関数 "unsigned int __stdcall MainThread(void *)" (?MainThread@@YGIPAX@Z) で参照されました。
ファイル:Siv3D_d.lib(Siv3DMain.obj)

エラー:LNK1120 1 件の未解決の外部参照 SimplePrototypeSystem
ファイル:SimplePrototypeSystem.exe


【ソースコード】
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

#include <iostream>
#include <vector>
#include<random>
#include<string>
#include<strstream>


#include <Siv3D.hpp>


int main()
{
//グレースケール入力
cv::Mat src = cv::imread("img.png", cv::IMREAD_GRAYSCALE);

// 画像の読み込みに失敗したらエラー終了する
if (src.empty())
{
std::cerr << "Failed to open image file." << std::endl;
return -1;
}

// 二値化
cv::threshold(src, src, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

//ラべリング処理
cv::Mat LabelImg;
cv::Mat stats;
cv::Mat centroids;
int nLab = cv::connectedComponentsWithStats(src, LabelImg, stats, centroids);

/*単体テスト以外では必要ない*/
// ラベリング結果の描画色を決定
std::vector<cv::Vec3b> colors(nLab);
colors[0] = cv::Vec3b(0, 0, 0);
for (int i = 1; i < nLab; ++i) {
colors[i] = cv::Vec3b((rand() & 255), (rand() & 255), (rand() & 255));
}

/*単体テスト以外では必要ない*/
// ラベリング結果の描画
cv::Mat Dst(src.size(), CV_8UC3);
for (int i = 0; i < Dst.rows; ++i) {
int *lb = LabelImg.ptr<int>(i);
cv::Vec3b *pix = Dst.ptr<cv::Vec3b>(i);
for (int j = 0; j < Dst.cols; ++j) {
pix[j] = colors[lb[j]];
}
}

//ROIの設定
for (int i = 1; i < nLab; ++i) {
int *param = stats.ptr<int>(i);
int x = param[cv::ConnectedComponentsTypes::CC_STAT_LEFT];
int y = param[cv::ConnectedComponentsTypes::CC_STAT_TOP];
int height = param[cv::ConnectedComponentsTypes::CC_STAT_HEIGHT];
int width = param[cv::ConnectedComponentsTypes::CC_STAT_WIDTH];

cv::rectangle(Dst, cv::Rect(x, y, width, height), cv::Scalar(0, 255, 0), 2);
}

int a[2];
int b[2];
//重心の出力
for (int i = 1; i < nLab; ++i) {
double *param = centroids.ptr<double>(i);
int x = static_cast<int>(param[0]);
int y = static_cast<int>(param[1]);

cv::circle(Dst, cv::Point(x, y), 3, cv::Scalar(0, 0, 255), -1);

std::cout << "centroids " << i << " = (" << x << " , " << y << ")" << std::endl;
if (i == 1) {
a[0] = x;
b[0] = y;
}
else if (i == 2) {
a[1] = x;
b[1] = y;
}
}

//面積値の出力
for (int i = 1; i < nLab; ++i) {
int *param = stats.ptr<int>(i);
std::cout << "area " << i << " = " << param[cv::ConnectedComponentsTypes::CC_STAT_AREA] << std::endl;

//ROIの左上に番号を書き込む
int x = param[cv::ConnectedComponentsTypes::CC_STAT_LEFT];
int y = param[cv::ConnectedComponentsTypes::CC_STAT_TOP];
std::stringstream num;
num << i;
cv::putText(Dst, num.str(), cv::Point(x + 5, y + 20), cv::FONT_HERSHEY_COMPLEX, 0.7, cv::Scalar(0, 255, 255), 2);
}

cv::imshow("Src", src);
cv::imshow("Labels", Dst);
cv::waitKey();


while (System::Update())
{
/*
ここは後々追加予定です
*/
}

return 0;
}
記事編集
keni  2016/09/21(Wed) 15:09
投稿した者です。

先ほどこの問題について解決しました。
失礼いたしました。
編集
Reputeless  2016/09/21(Wed) 23:27
解決されたようですが、説明を書きます。

[1]
Siv3D アプリの開発では void Main() 関数をエントリーポイントとします。
一般的な C++ プログラムの int main() は使えません。

[2]
Siv3D で OpenCV を使うには、OpenCV へのインクルードパスを通したうえで
# include <opencv2/opencv.hpp>
をインクルードしてください。

ライブラリファイルは Siv3D に付属しているものが使えるので、特別な操作は不要です。
Siv3D August 2016 v2 では OpenCV 3.0.0 に対応しています。

[3]
Siv3D に付属しない OpenCV モジュールの関数を使用した場合、リンカエラーになります。
その場合は必要なモジュールの .lib を追加でリンクしてください。

この際、OpenCV に最初から付属している .lib ファイルを使用するとランタイムエラーが生じることがあります。
お手数ですが、必要なモジュールの .lib ファイルを自前でビルドしてください。
(Debug 用は /MTd, Release 用は /MT オプションを選択してください。)


こちらも参考にしてください
http://siv3d.jp/bbs/patio.cgi?read=100&ukey=0
編集
件名
Re: Siv3Dとopencvの併用について
名前
コメント
画像添付


投稿修正キー (投稿を修正する時に使います)
画像認証 (右画像の数字を入力) 投稿キー

- WEB PATIO -