diff --git a/UmaUmaChecker/CombineImage.cpp b/UmaUmaChecker/CombineImage.cpp index 045a6ea..4ba8ed1 100644 --- a/UmaUmaChecker/CombineImage.cpp +++ b/UmaUmaChecker/CombineImage.cpp @@ -56,6 +56,7 @@ void CombineImage::StartCapture() Images.clear(); DetectedYLines.clear(); BarLength = 0; + Error = L""; LOG_DEBUG << L"[CombineImage::StartCapture] ウマ娘詳細結合開始"; @@ -131,10 +132,11 @@ bool CombineImage::Combine() return false; } -void CombineImage::_EndCapture() +void CombineImage::_EndCapture(const std::wstring& error) { if (!IsCapture) return; + Error = error; IsCapture = false; status = Stop; } @@ -158,9 +160,9 @@ void CombineImage::Capture() if (BarLength == 0 && scroll.GetBarLength() > 0) BarLength = scroll.GetBarLength(); - if (!IsScanStarted && scroll.GetBarLength() == 0) { + if (!IsScanStarted && (!scroll.IsValid() || scroll.GetBarLength() == 0)) { LOG_DEBUG << L"[CombineImage::Capture] 停止, !IsScanStarted && scroll.GetBarLength() == 0"; - _EndCapture(); + _EndCapture(L"スクロールバーを検出できませんでした。"); // 通常キャプチャ delete image; return; @@ -173,18 +175,17 @@ void CombineImage::Capture() status = WaitForMovingScrollbarOnTop; } - if (BarLength > 0 && std::abs(BarLength - scroll.GetBarLength()) > 1) { - if (IsManualStop) { - LOG_DEBUG << L"[CombineImage::Capture] 停止, BarLength > 0 && std::abs(BarLength - scroll.GetBarLength()) > 1) && IsManualStop"; - _EndCapture(); - } + if (!PrevImage.empty() && (PrevImage.size().width != mat.size().width || PrevImage.size().height != mat.size().height)) { + LOG_DEBUG << L"[CombineImage::Capture] 停止, !PrevImage.empty() && (PrevImage.size().width != mat.size().width || PrevImage.size().height != mat.size().height)"; + _EndCapture(L"ウィンドウサイズが変更されました。"); delete image; return; } - - if (!PrevImage.empty() && (PrevImage.size().width != mat.size().width || PrevImage.size().height != mat.size().height)) { - LOG_DEBUG << L"[CombineImage::Capture] 停止, !PrevImage.empty() && (PrevImage.size().width != mat.size().width || PrevImage.size().height != mat.size().height)"; - _EndCapture(); + else if (BarLength > 0 && std::abs(BarLength - scroll.GetBarLength()) > 1) { + if (IsManualStop) { + LOG_DEBUG << L"[CombineImage::Capture] 停止, BarLength > 0 && std::abs(BarLength - scroll.GetBarLength()) > 1) && IsManualStop"; + _EndCapture(L"スクロールバーの大きさが変わっています。"); + } delete image; return; } @@ -250,6 +251,7 @@ void CombineImage::Capture() DetectedYLines.emplace_back(0, y); IsFirstScan = false; CurrentScrollPos = scroll.GetPos(); + PrevImage = mat.clone(); } } } diff --git a/UmaUmaChecker/CombineImage.h b/UmaUmaChecker/CombineImage.h index d567c89..cd6d3ae 100644 --- a/UmaUmaChecker/CombineImage.h +++ b/UmaUmaChecker/CombineImage.h @@ -2,6 +2,7 @@ #include #include +#include struct CombineImageInfo { int StartY; @@ -29,6 +30,7 @@ class CombineImage int GetProgressTime() const { return msec; } CombineStatus GetStatus() const { return status; } bool IsImageSaved() const { return IsSavedImage; } + std::wstring GetError() const { return Error; } bool IsCapturing() const { return IsCapture; } void StartCapture(); @@ -37,7 +39,7 @@ class CombineImage bool Combine(); private: - void _EndCapture(); + void _EndCapture(const std::wstring& error = L""); void Capture(); int GetTemplateImage(const cv::Mat& mat, cv::Mat& cut); @@ -61,6 +63,8 @@ class CombineImage bool IsManualStop; bool IsSavedImage; + std::wstring Error; + std::vector DetectedYLines; std::vector Images; diff --git a/UmaUmaChecker/MainFrame.cpp b/UmaUmaChecker/MainFrame.cpp index 2600d71..3ab6c3b 100644 --- a/UmaUmaChecker/MainFrame.cpp +++ b/UmaUmaChecker/MainFrame.cpp @@ -131,11 +131,6 @@ MainFrame::MainFrame(wxWindow* parent, const wxPoint& pos, const wxSize& size, l m_comboPopup = new wxComboBoxPopup(this); - this->SetSizer(bSizerTop); - this->Fit(); - this->Layout(); - this->Centre(wxBOTH); - // イベントバインド this->Bind(wxEVT_CLOSE_WINDOW, &MainFrame::OnClose, this); m_toggleBtnStart->Bind(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, &MainFrame::OnClickStart, this); @@ -167,6 +162,10 @@ MainFrame::MainFrame(wxWindow* parent, const wxPoint& pos, const wxSize& size, l if (!config->IsShowStatusBar) m_statusBar->Hide(); else timer.Start(1000); + this->SetSizer(bSizerTop); + this->Fit(); + this->Layout(); + Init(); } @@ -343,7 +342,9 @@ void MainFrame::OnClickCombine(wxCommandEvent& event) CombineTimer.Stop(); this->SetTitle(app_title); if (!combine.IsImageSaved()) { - wxMessageBox(wxT("キャプチャに失敗しました。"), app_title, wxICON_ERROR); + std::wstring error = combine.GetError(); + if (!error.empty()) wxMessageBox(error, app_title, wxICON_ERROR); + else wxMessageBox(wxT("キャプチャに失敗しました。"), app_title, wxICON_ERROR); } } } diff --git a/UmaUmaChecker/Point.h b/UmaUmaChecker/Point.h new file mode 100644 index 0000000..30b74b7 --- /dev/null +++ b/UmaUmaChecker/Point.h @@ -0,0 +1,19 @@ +#pragma once + +template +class Point +{ +public: + Point() {} + Point(T x, T y) : x_(x), y_(y) {} + + T x() const { return x_; } + T y() const { return y_; } + + void x(const T& x) { x_ = x; } + void y(const T& y) { y_ = y; } + +private: + T x_, y_; +}; + diff --git a/UmaUmaChecker/ScrollbarDetector.cpp b/UmaUmaChecker/ScrollbarDetector.cpp index c661683..58c148e 100644 --- a/UmaUmaChecker/ScrollbarDetector.cpp +++ b/UmaUmaChecker/ScrollbarDetector.cpp @@ -1,10 +1,14 @@ #include "ScrollbarDetector.h" +#include #include -ScrollbarDetector::ScrollbarDetector(cv::Mat& img) +Point ScrollbarDetector::Start(0.967, 0.08); +Point ScrollbarDetector::End(0.967, 1.0 - 0.08); + +ScrollbarDetector::ScrollbarDetector(cv::Mat& img) : valid(false) { InitScrollInfo(img); } @@ -13,73 +17,124 @@ ScrollbarDetector::~ScrollbarDetector() { } +bool ScrollbarDetector::IsValid() const +{ + return valid; +} + int ScrollbarDetector::GetPos() const { - return StartY; + return valid ? ScrollBarStartY : 0; } int ScrollbarDetector::GetTotalLength() const { - return TotalLength; + return valid ? TotalLength : 0; } int ScrollbarDetector::GetBarLength() const { - return Length; + return valid ? Length : 0; } int ScrollbarDetector::GetBarLengthRatio() const { - return (double)Length / TotalLength * 100; + return valid ? (double)Length / TotalLength * 100 : 0; } bool ScrollbarDetector::IsBegin() const { - return StartY == 0; + return valid && ScrollBarStartY == MinY; } bool ScrollbarDetector::IsEnd() const { - return EndY + 1 == TotalLength; + return valid && ScrollBarEndY == MaxY; } void ScrollbarDetector::InitScrollInfo(cv::Mat& img) { - TotalLength = img.size().height; + TotalLength = 0; Length = 0; - StartY = EndY = -1; + ScrollBarStartY = ScrollBarEndY = -1; - cv::Mat scr; - cv::inRange(img, cv::Scalar(140, 121, 123), cv::Scalar(180, 179, 189), scr); + cv::Mat bar, scr; + cv::inRange(img, cv::Scalar(140, 121, 123), cv::Scalar(180, 179, 189), bar); + cv::inRange(img, cv::Scalar(140, 121, 123), cv::Scalar(217, 210, 211), scr); + MinY = -1; + MaxY = -1; for (int y = 0; y < scr.size().height; y++) { - cv::uint8_t c = scr.at(y, 2); - if (c == 255 && StartY == -1) { - /* - bool hasBlack = false; - for (int x = 0; x < scr.size().width; x++) { - cv::uint8_t bw = scr.at(y, x); - if (bw == 0) { - hasBlack = true; - break; - } + for (int x = 0; x < scr.size().width; x++) { + cv::uint8_t b = scr.at(y, x); + if (b == 255) { + if (MinY == -1) MinY = y; + if (y > MaxY) MaxY = y; } + } + } + + if (MinY == -1 || MaxY == -1) return; + + TotalLength = MaxY - MinY; + + for (int y = MinY; y <= MaxY; y++) { + cv::uint8_t c = 0; - if (!hasBlack) */ - StartY = y; + for (int x = 0; x < bar.size().width && c != 255; x++) c = bar.at(y, x); + + if (c == 255 && ScrollBarStartY == -1) { + ScrollBarStartY = y; } - else if (c == 0 && StartY != -1 && EndY == -1) { - EndY = y - 1; + else if (c == 0 && ScrollBarStartY != -1 && ScrollBarEndY == -1) { + ScrollBarEndY = y - 1; break; } } - if (StartY == -1 && EndY == -1) { + if (ScrollBarStartY == -1 && ScrollBarEndY == -1) { return; } - if (EndY == -1) EndY = scr.size().height - 1; + if (ScrollBarEndY == -1) ScrollBarEndY = MaxY; + + Length = ScrollBarEndY - ScrollBarStartY; + valid = true; +} + +std::list> ScrollbarDetector::GetMargin(cv::Mat& img) +{ + auto start = Point(img.size().width * Start.x(), img.size().height * Start.y()); + auto end = Point(img.size().width * End.x(), img.size().height * End.y()); + + cv::Mat scr; + cv::inRange(img, cv::Scalar(140, 121, 123), cv::Scalar(217, 210, 211), scr); + + cv::Mat test; + cv::inRange(img, cv::Scalar(170, 151, 153), cv::Scalar(255, 255, 255), scr); + cv::inRange(img, cv::Scalar(170, 151, 153), cv::Scalar(255, 255, 255), scr); + + std::once_flag once_start; + Point pos_start; + Point pos_end; + + for (int y = start.y(); y < end.y(); y++) { + auto c = scr.at(y, start.x()); + if (c == 255) { + std::call_once(once_start, [&] { + pos_start.x(start.x()); + pos_start.y(y); + }); + pos_end.x(start.x()); + pos_end.y(y); + } + else + break; + } - Length = EndY - StartY; + return { + pos_start, + pos_end + }; } diff --git a/UmaUmaChecker/ScrollbarDetector.h b/UmaUmaChecker/ScrollbarDetector.h index 636a760..1842295 100644 --- a/UmaUmaChecker/ScrollbarDetector.h +++ b/UmaUmaChecker/ScrollbarDetector.h @@ -1,5 +1,9 @@ #pragma once +#include + +#include "Point.h" + namespace cv { class Mat; } @@ -10,6 +14,7 @@ class ScrollbarDetector ScrollbarDetector(cv::Mat& img); ~ScrollbarDetector(); + bool IsValid() const; int GetPos() const; int GetTotalLength() const; int GetBarLength() const; @@ -20,10 +25,22 @@ class ScrollbarDetector private: void InitScrollInfo(cv::Mat& img); + std::list> GetMargin(cv::Mat& img); + +private: + static Point Start; + static Point End; + private: + bool valid; + int TotalLength; int Length; - int StartY; - int EndY; + + int ScrollBarStartY; + int ScrollBarEndY; + + int MinY; + int MaxY; }; diff --git a/UmaUmaChecker/UmaUmaChecker.vcxproj b/UmaUmaChecker/UmaUmaChecker.vcxproj index 2f479bf..f7aed32 100644 --- a/UmaUmaChecker/UmaUmaChecker.vcxproj +++ b/UmaUmaChecker/UmaUmaChecker.vcxproj @@ -273,6 +273,7 @@ + diff --git a/UmaUmaChecker/UmaUmaChecker.vcxproj.filters b/UmaUmaChecker/UmaUmaChecker.vcxproj.filters index c477dc4..13d0203 100644 --- a/UmaUmaChecker/UmaUmaChecker.vcxproj.filters +++ b/UmaUmaChecker/UmaUmaChecker.vcxproj.filters @@ -227,6 +227,9 @@ ヘッダー ファイル + + ヘッダー ファイル +