Мы пишем программу, которая получает данные с веб-камеры, вычитает все цвета, кроме значений зеленого цвета, находит отдельные BLOB-объекты и нумерует их. В конце концов, это будет использоваться в качестве входа для видеоигры, но сейчас это не имеет значения.
Код, о котором идет речь, - это не код, который фактически делает все это, а переписанный сегмент кода, чтобы проверить, как на самом деле работает FindContours.
Обычно, при обработке изображений, мы думали, что изображение читается сверху вниз, справа налево, но после некоторого тестирования кажется, что оно делает противоположное, начиная с нижнего правого угла и двигаясь в верхний левый! *
Итак, вопрос здесь: в каком порядке FindContours находит его Contours? Я прав в своем предположении, или это мой собственный код, сбивающий меня с толку?
Ввод: Blobtest06
Окно "Компоненты"
Консоль
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/core/mat.hpp>
#include <Windows.h> //for sleep function
using namespace cv;
using namespace std;
void IsolateGreen(Mat mIn, Mat& mOut)
{
Mat inImg (mIn.rows, mIn.cols, CV_8UC3, Scalar(1,2,3));
inImg.data = mIn.data;
Mat channelRed (inImg.rows, inImg.cols, CV_8UC1);
Mat channelGreen (inImg.rows, inImg.cols, CV_8UC1);
Mat channelBlue (inImg.rows, inImg.cols, CV_8UC1);
Mat outImg[] = {channelRed, channelGreen, channelBlue};
int fromTo[] = { 0,2, 1,1, 2,0};
mixChannels( &inImg, 1, outImg, 3, fromTo, 3);
mOut = (channelGreen) - (channelRed + channelBlue);
threshold(mOut, mOut, 5, 255, THRESH_BINARY);
erode(mOut, mOut, Mat(), Point (-1,-1), 1);
dilate(mOut, mOut, Mat(), Point(-1,-1), 2);
}
void FindContours(Mat& mDst, Mat mGreenScale, vector<vector<Point>>& vecContours, vector<Vec4i>& vecHierarchy, Mat img)
{
//This is empty at all times. We need it to avoid crashes.
vector<Vec4i> vecHierarchy2;
// mGreenScale = mGreenScale > 1; //// MIGHT be entirely unneeded
mDst = img > 1;
findContours( mGreenScale, vecContours, vecHierarchy,
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
/* Colors, in order:
1st. = Red
2nd. = Dark red
3rd. = Purple
4th. = Blue
5th. = Baby blue
6th. = Green
7th. = Olive green
8th. = Dark green
*/
int aRed[] = {255, 100, 128, 0, 191, 0, 202, 0};
int aGreen[] = {0, 0, 0, 0, 239, 255, 255, 100};
int aBlue[] = {0, 0, 128, 255, 255, 0, 112, 0};
string sColor[] = {"Red", "Dark red", "Purple", "Blue", "Baby blue", "Green", "Light green", "Dark green"};
//its important that we check if there is anything in vecHierarchy (else) {crash} :P
//function drawContours cannot handle an empty vedHierarchy
if (vecHierarchy != vecHierarchy2)
{
// iterate through all the top-level contours,
for(int idx = 0; idx >= 0; idx = vecHierarchy[idx][0] )
{
// draw each connected component with its own FIXED color
Scalar color( aBlue[idx], aGreen[idx], aRed[idx] );
drawContours( mDst, vecContours, idx, color, /*1*/ CV_FILLED, 8, vecHierarchy );
cout << vecContours[idx][0] << " - - " << sColor[idx] << " - - Index: " << idx << endl;
}
}
cout << "Objects: ";
cout << vecContours.size();
cout << endl;
}
int main()
{
Mat img = imread("Blobtest06.png");
Mat mGreenScale;
//These next 5 instances ties to contourfinding
cvtColor(img, mGreenScale, CV_8UC3); //sets the right rows and cols
vector<vector<Point>> vecContours; //points to each pixel in a contour
vector<Vec4i> vecHierarchy; //A hierarchy for the functions
Mat mDst = Mat::zeros(mGreenScale.rows, mGreenScale.cols, CV_8UC3); //mDst image
IsolateGreen(img, mGreenScale);
FindContours(mDst, mGreenScale, vecContours, vecHierarchy, img);
namedWindow( "Components", 1 );
imshow( "Components", mDst );
namedWindow( "Source", 1 );
imshow( "Source", mGreenScale );
waitKey();
return 0;
}
PS: извините за ужасный синтаксис. Сайт трудный, и он только на обеде.