Wektor punktów

0

Witam, mam następujący problem: próbuje odfiltrować wektor współrzędnych wierzchołków figury płaskiej odczytanej z jpg. Przykładowo do trójkąt otrzymałem 9 punktów z czego 3 są faktycznymi wierzchołkami a pozostałe 6 to szum. Do rozwiązania zadanie jest mi jedynie potrzebna liczba wierzchołków( ich współrzędne są mi nie potrzebne). Jak się pozbyć zbędych punktów.

Przykładowy wektor punktów jaki otrzymuje:
[ 468, 62;
468, 63;
468,64;
360, 495;
361,495;
361,496;
575, 507;
576, 507;
575, 508]
Na podstawie tych wektorów chciałbym otrzymać informacje zwrotną że punktów jest 3(w tym przypadku).
Pozdrawiam

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace cv;
using namespace std;

Mat OurImage,grayframe,binaryframe;
void cornerHarris_demo( int, void* );

int main()
{

string Destination = "D:\\...\\NoveltyDetectionData\\Set1\\TRAINING_DATA\\007.jpg";
OurImage = imread(Destination, CV_LOAD_IMAGE_COLOR);
if(! OurImage.data)
{
printf("No image!");
getchar();
return -1;
}
cvtColor(OurImage,grayframe,CV_RGB2GRAY);
threshold(grayframe, binaryframe, 150, 255,0);

namedWindow("WINDOW", CV_WINDOW_AUTOSIZE);
imshow("WINDOW",binaryframe);

cornerHarris_demo( 0, 0 );

waitKey(0);
}

void cornerHarris_demo( int, void* )
	{
	Mat dst, dst_norm, dst_norm_scaled;
	dst = Mat::zeros( OurImage.size(), CV_32FC1 );
	/// Detector parameters
	int blockSize = 2;
	int apertureSize = 3;
	double k = 0.04;
	/// Detecting corners
	cornerHarris( grayframe, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
	/// Normalizing
	normalize( dst, dst_norm, 0, 200, NORM_MINMAX, CV_32FC1, Mat() );
	convertScaleAbs( dst_norm, dst_norm_scaled );
	/// Drawing a circle around corners
	Point punkt;
	vector <Point> Punkty;
	int x,y,counter=0;
	
	for( int j = 0; j < dst_norm.rows ; j++ )
		{ 
			for( int i = 0; i < dst_norm.cols; i++ )
			{
				if( (int) dst_norm.at<float>(j,i) > 80)
				{
					counter++;
					circle( dst_norm_scaled, Point( i, j ), 25, Scalar(200,200,200), 2, 8, 0 );
					punkt.x=i;
					punkt.y=j;
					Punkty.push_back(punkt);
					cout << punkt<< endl;				
				}
			}
		}
	
	cout <<counter<< endl;
	cout << Punkty<< endl;

	/// Showing the result
	namedWindow( "corners_window", CV_WINDOW_AUTOSIZE );
	imshow( "corners_window", dst_norm_scaled );
	}
 
0

Dopisałem coś takiego:

int a=2;
	for( int i = 0; i < counter; i++ )
		{ 
			cout <<"."<< endl;
			for( int j = 1; j < counter; j++ )
			{
				cout <<j<< endl;
				if(abs(Punkty[i].x-Punkty[j].x)<=a || abs(Punkty[i].y-Punkty[j].y)<=a)
					Punkty.erase( Punkty.begin() + j );
					 //Punkty.erase( Punkty.begin() + Punkty[j].ID - 1 );
					;
			}
		} 

warunek jest sensowy bo zamiast jednego punktu z wierzchołka otrzymuje ok 3 które się różnią pikselem. Jednak program zwraca błąd: vector subscript out of range. Ponoć usuwam element a później się do niego odwołuje, ale nie umiem się z tym uprać. Ponoć można jeszcze na remove_if ale z tym też kiepsko u mnie, za wszelkie porady dzięki.

0
  1. Zapoznaj się z pojęciem formatowania kodu: http://4programmers.net/Forum/998482
  2. Zapoznaj się z inkrementacją, bo jej nie rozumiesz: http://4programmers.net/Forum/1101404
  3. Nie używaj innego niż angielskie nazewnictwa: http://4programmers.net/Forum/1208091
  4. Może wytłumacz co za punkty otrzymujesz i jak oni się mają do tego trójkąta. Czy masz znaleźć taki trójkąt który obejmuje (zawiera wewnątrz) wszystkie punkty? Czy wiesz że to nie koniecznie może się udać (wyobraź sobie cztery punkty stanowiące wierzchołki kwadratu)?
0

Przykładowo mam taki obraz:
001.jpg
Muszę z niego odczytać faktyczną liczbę wierzchołków( czyli w tym przypadku 3), jednak program zwraca mi ich więcej ok. 9
Przykładowy wektor punktów jaki mi zwraca program to:
[ 468, 62;
468, 63;
468,64;
360, 495;
361,495;
361,496;
575, 507;
576, 507;
575, 508]
Widać w nim że każde 3 punkty są podobne do siebie różnią się o jeden piksel na x lub na y. To co chce otrzymać to z tego wektora to ilość wierzchołków czyli liczbę 3 a nie 9. Dodatkowo nie interesuje mnie dokładne współrzędne danego wierzchołka. Warunek który napisałem:

 int a=2;
    for( int i = 0; i < counter; i++ )
        { 
            cout <<"."<< endl;
            for( int j = 1; j < counter; j++ )
            {
                cout <<j<< endl;
                if(abs(Punkty[i].x-Punkty[j].x)<=a || abs(Punkty[i].y-Punkty[j].y)<=a)
                    Punkty.erase( Punkty.begin() + j );
                     //Punkty.erase( Punkty.begin() + Punkty[j].ID - 1 );
                    ;
            }
        } 

prawdopodobnie załatwiłby całą sprawę ale program zwraca błąd.
Przechwytywanie.PNG

0

Najpierw określ gdzie leży trójkąt, wtedy będziesz mógł odrzucać resztę (o ile to w ogóle ma sens - antyaliasing).
W ostatnim poście masz problem techniczny, wychodzisz poza zakres wektora (bo iterujesz po całości w międzyczasie kasując sobie niektóre z nich po drodze).

0

Warunek usuwania powinien być taki

if(abs(Punkty[i].x-Punkty[j].x)<=a && abs(Punkty[i].y-Punkty[j].y)<=a)
2
#include <iostream>
#include <vector>
using namespace std;

struct Point { int x,y; };

int main()
  {
   vector<Point> PointArray
     {
       {468,  62},
       {468,  63},
       {468,  64},
       {360, 495},
       {361, 495},
       {361, 496},
       {575, 507},
       {576, 507},
       {575, 508}
     };
   for(vector<Point>::iterator i=PointArray.begin(),k;i!=PointArray.end();++i)
     {
      int ix=i->x,iy=i->y;
      double sx=ix,sy=iy;
      size_t count=1;
      for(k=i,++k;k!=PointArray.end();)
        {
         int kx=k->x,ky=k->y,dx=ix-kx,dy=iy-ky;
         if(dx*dx+dy*dy<=4)
           {
            sx+=kx;
            sy+=ky;
            ++count;
            k=PointArray.erase(k);
           }
         else ++k;
        }
      i->x=(sx+0.5)/count;
      i->y=(sy+0.5)/count;
     }
   for(vector<Point>::iterator i=PointArray.begin();i!=PointArray.end();++i) cout<<i->x<<','<<i->y<<endl;
   return 0;
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1