Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ set(CMAKE_DEBUG_POSTFIX "_d")

option(BUILD_SHARED_LIBS "build with shared libraries" OFF)

find_package( OpenCV REQUIRED )
find_package(OpenCV 4.2.0 REQUIRED )

IF(WIN32)
set(PTHREADS_INCLUDE_DIR "" CACHE PATH "Pthreads Include Directory")
Expand Down
91 changes: 15 additions & 76 deletions example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <fstream>
#include "blob.h"
#include "BlobResult.h"
#include "highgui.h" //include it to use GUI functions.
#include <opencv2/highgui.hpp>

const int NUMCORES = 2;
using namespace std;
Expand All @@ -19,94 +19,33 @@ void testJoin();
void testRandomImage(); //Generate a random image and test blobs.

int main(){
// testTimes(500,3000,250,"TempiHR",20);
//testTimes(1000,1000,20,"TempiLR",40);
//testTimes(10,2000,50,"TempiRandom",15);
//opencvLogo();
//test();
testJoin();
//testMio();
//testRandomImage();

cout <<"Press a key to continue..."<<endl;
cin.get();
return 0;
}

/*void testTimes(int startRes,int endRes, int step,string fileName, int iter){
ofstream fileOutST(fileName+"ST.txt");
ofstream fileOutMT(fileName+"MT.txt");
ofstream fileOutInfo(fileName+"Info.txt");
char CPUBrandString[49];
__cpuid((int*)CPUBrandString, 0x80000002);
__cpuid((int*)(CPUBrandString+16), 0x80000003);
__cpuid((int*)(CPUBrandString+32), 0x80000004);
CPUBrandString[48] = 0;
fileOutInfo << CPUBrandString;
int64 time;
double elapsed;
RNG random;
Mat color_img = imread("testImage.png");
Mat temp_color_img;
CBlobResult res;
cvtColor(color_img,color_img,CV_BGR2GRAY);
for(int i=0;i<=(endRes-startRes)/step;i++){
int resolution = step*i+startRes;
temp_color_img = color_img.clone();
resize(color_img,temp_color_img,Size(resolution,resolution),0,0,INTER_NEAREST);
threshold(temp_color_img,temp_color_img,250,255,CV_THRESH_BINARY_INV);
//namedWindow("image",CV_WINDOW_NORMAL + CV_GUI_EXPANDED + CV_WINDOW_KEEPRATIO);
//imshow("image",temp_color_img);
//waitKey();
cout <<"RISOLUZIONE: " << resolution<<"x"<<resolution<<endl;
fileOutST << resolution;
Mat mt;
for(int j=0;j<iter;j++){
time=getTickCount();
CBlobResult res(temp_color_img,mt,1);
elapsed = (getTickCount()-time)/getTickFrequency();
cout <<j<<"/"<<iter<<"\tTempo Single Thread: " <<elapsed<<"\t Nblobs: "<<res.GetNumBlobs()<<"\tTime: "<<endl;
fileOutST <<"\t" << elapsed;
}
fileOutST << "\n";
fileOutMT << resolution;

//cout <<"MULTITHREAD"<<endl;
for(int j=0;j<iter;j++){
time=getTickCount();
CBlobResult res(temp_color_img,mt,NUMCORES);
//CBlobResult res(&(IplImage)temp_color_img,NULL,0,NUMCORES);
elapsed = (getTickCount()-time)/getTickFrequency();
cout <<j<<"/"<<iter<<"\tTempo Multi Thread: " <<elapsed<<"\t Nblobs: "<<res.GetNumBlobs()<<"\tTime: "<<endl;
fileOutMT <<"\t" << elapsed;
}
fileOutMT << "\n";
}
fileOutST.close();
fileOutMT.close();
fileOutInfo.close();
}*/

void test()
{
int64 time;
RNG random;
Mat color_img = imread("opencvblobslibBIG.png");
//resize(color_img,color_img,Size(IMSIZE,IMSIZE),0,0,INTER_LINEAR);
namedWindow("Color Image",CV_WINDOW_NORMAL);
namedWindow("Gray Image",CV_WINDOW_NORMAL);
namedWindow("Binary Image",CV_WINDOW_NORMAL);
namedWindow("Blobs Image",CV_WINDOW_NORMAL);
namedWindow("Color Image",cv::WINDOW_NORMAL);
namedWindow("Gray Image",cv::WINDOW_NORMAL);
namedWindow("Binary Image",cv::WINDOW_NORMAL);
namedWindow("Blobs Image",cv::WINDOW_NORMAL);
imshow("Color Image",color_img);
Mat binary_img(color_img.size(),CV_8UC1);
cvtColor(color_img,binary_img,CV_BGR2GRAY);
cvtColor(color_img,binary_img,cv::COLOR_BGR2GRAY);
imshow("Gray Image",binary_img);
threshold(binary_img,binary_img,250,255,CV_THRESH_BINARY_INV);
threshold(binary_img,binary_img,250,255,cv::THRESH_BINARY_INV);
imshow("Binary Image",binary_img);
CBlobResult blobs;
color_img.setTo(Vec3b(0,0,0));
time=getTickCount();
IplImage temp = (IplImage)binary_img;
cv::Mat temp = (cv::Mat)binary_img;
blobs = CBlobResult(&temp,NULL,1);
cout <<"found: "<<blobs.GetNumBlobs()<<endl;
cout <<"Tempo ST: "<<(getTickCount() -time)/getTickFrequency()<<endl;
Expand Down Expand Up @@ -156,8 +95,8 @@ void opencvLogo()
{
Mat im = imread("opencvblobslibBIG.png");
Mat img;
cvtColor(im,img,CV_BGR2GRAY);
threshold(img,img,254,255,CV_THRESH_BINARY_INV);
cvtColor(im,img,cv::COLOR_BGR2GRAY);
threshold(img,img,254,255,cv::THRESH_BINARY_INV);
int64 time = getTickCount();
CBlobResult res(img,Mat(),NUMCORES);
cout << "Tempo: " << (getTickCount() - time)/getTickFrequency();
Expand All @@ -175,8 +114,8 @@ void opencvLogo()
void testJoin(){
Mat im = imread("opencvblobslibBIG.png");
Mat img,imt,im2;
cvtColor(im,img,CV_BGR2GRAY);
threshold(img,imt,254,255,CV_THRESH_BINARY_INV);
cvtColor(im,img,cv::COLOR_BGR2GRAY);
threshold(img,imt,254,255,cv::THRESH_BINARY_INV);
//imt = imt(Rect(30,50,100,100));
imshow("binImage",imt);
CBlobResult res(imt,Mat(),NUMCORES);
Expand Down Expand Up @@ -295,15 +234,15 @@ void testJoin(){
void testRandomImage()
{
cout << "Random test: Press esc to quit"<<endl;
namedWindow("Binary Image",CV_WINDOW_NORMAL);
namedWindow("Blobs Image",CV_WINDOW_NORMAL);
namedWindow("Binary Image",cv::WINDOW_NORMAL);
namedWindow("Blobs Image",cv::WINDOW_NORMAL);
Mat image(256,256,CV_8UC1),nulMask;
Mat out(image.size(),CV_8UC3);
RNG rand(0);
while(true){
out.setTo(0);
rand.fill(image,CV_8UC1,0,256);
threshold(image,image,127,255,CV_THRESH_BINARY);
threshold(image,image,127,255,cv::THRESH_BINARY);
CBlobResult res(image,nulMask,2);
cout << "Nblobs: "<< res.GetNumBlobs()<<endl;
for(int i=0;i<res.GetNumBlobs();i++){
Expand Down
57 changes: 26 additions & 31 deletions library/BlobContour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ CBlobContour::CBlobContour()
m_moments.m00 = -1;
parent=NULL;
}
CBlobContour::CBlobContour(CvPoint startPoint, const Size &imageRes):m_contour(1)
CBlobContour::CBlobContour(cv::Point startPoint, const Size &imageRes):m_contour(1)
{

m_startPoint.x = startPoint.x;
Expand Down Expand Up @@ -72,17 +72,17 @@ CBlobContour& CBlobContour::operator=( const CBlobContour &source )


/**
- FUNCI�: AddChainCode
- FUNCI�: AddChainCode
- FUNCIONALITAT: Add chain code to contour
- PAR�METRES:
- PAR�METRES:
-
- RESULTAT:
-
- RESTRICCIONS:
-
- AUTOR: rborras
- DATA DE CREACI�: 2008/05/06
- MODIFICACI�: Data. Autor. Descripci�.
- DATA DE CREACI�: 2008/05/06
- MODIFICACI�: Data. Autor. Descripci�.
*/
void CBlobContour::AddChainCode(t_chainCode chaincode)
{
Expand All @@ -97,17 +97,17 @@ void CBlobContour::Reset()
}

/**
- FUNCI�: GetPerimeter
- FUNCI�: GetPerimeter
- FUNCIONALITAT: Get perimeter from chain code. Diagonals sum sqrt(2) and horizontal and vertical codes 1
- PAR�METRES:
- PAR�METRES:
-
- RESULTAT:
-
- RESTRICCIONS:
-
- AUTOR: rborras
- DATA DE CREACI�: 2008/04/30
- MODIFICACI�: Data. Autor. Descripci�.
- DATA DE CREACI�: 2008/04/30
- MODIFICACI�: Data. Autor. Descripci�.
- NOTA: Algorithm derived from "Methods to estimate area and perimeters of blob-like objects: A comparison", L.Yang
*/
double CBlobContour::GetPerimeter()
Expand All @@ -126,17 +126,17 @@ double CBlobContour::GetPerimeter()
}

/**
- FUNCI�: GetArea
- FUNCI�: GetArea
- FUNCIONALITAT: Computes area from chain code
- PAR�METRES:
- PAR�METRES:
-
- RESULTAT:
- May give negative areas for clock wise contours
- RESTRICCIONS:
-
- AUTOR: rborras
- DATA DE CREACI�: 2008/04/30
- MODIFICACI�: Data. Autor. Descripci�.
- DATA DE CREACI�: 2008/04/30
- MODIFICACI�: Data. Autor. Descripci�.
- NOTA: Algorithm derived from "Properties of contour codes", G.R. Wilson
*/
double CBlobContour::GetArea()
Expand All @@ -157,23 +157,18 @@ double CBlobContour::GetArea()
//! Get contour moment (p,q up to MAX_CALCULATED_MOMENTS)
double CBlobContour::GetMoment(int p, int q)
{
// is a valid moment?
if ( p < 0 || q < 0 || p > MAX_MOMENTS_ORDER || q > MAX_MOMENTS_ORDER )
{
// Assuming m_moments is of type cv::Moments and has been calculated earlier
if ( p < 0 || q < 0 || p > MAX_MOMENTS_ORDER || q > MAX_MOMENTS_ORDER ) {
return -1;
}

if( IsEmpty() )
return 0;

// it is calculated?
if( m_moments.m00 == -1)
{
//cvMoments( GetContourPoints(), &m_moments );
m_moments = moments(GetContourPoints(),true);
}

return cvGetSpatialMoment( &m_moments, p, q );
else if (p == 0 && q == 0) return m_moments.m00;
else if (p == 1 && q == 0) return m_moments.m10;
else if (p == 0 && q == 1) return m_moments.m01;
// Add more conditions for other moments you need
else {
// Handle error or unsupported moments
return -1;
}

}

Expand Down Expand Up @@ -218,7 +213,7 @@ void CBlobContour::ShiftBlobContour(int x,int y)
}


t_chainCode points2ChainCode( CvPoint p1, CvPoint p2 )
t_chainCode points2ChainCode( cv::Point p1, cv::Point p2 )
{
// /* Luca Nardelli & Saverio Murgia
// Freeman Chain Code:
Expand Down Expand Up @@ -246,14 +241,14 @@ t_chainCode points2ChainCode( CvPoint p1, CvPoint p2 )
else
return 200;
}
CvPoint chainCode2Point(CvPoint origin,t_chainCode code){
cv::Point chainCode2Point(cv::Point origin,t_chainCode code){
// /* Luca Nardelli & Saverio Murgia
// Freeman Chain Code:
// 321 Values indicate the chain code used to identify next pixel location.
// 4-0 If I join 2 blobs I can't just append the 2nd blob chain codes, since they will still start
// 567 from the 1st blob start point
// */
CvPoint pt = origin;
cv::Point pt = origin;
switch(code){
case 0:pt.x++;break;
case 1:pt.x++;pt.y--;break;
Expand Down
17 changes: 8 additions & 9 deletions library/BlobContour.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@


#include "list"
#include "opencv/cv.h"
#include "opencv/cxcore.h"
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <list>

Expand Down Expand Up @@ -35,7 +34,7 @@ class CBlobContour
CBlobContour();
//Size is used to empirically reserve internal vectors for contour points.
//This can be a help for very small images, where the vector would be too large.
CBlobContour(CvPoint startPoint, const cv::Size &imageRes = cv::Size(-1,-1));
CBlobContour(cv::Point startPoint, const cv::Size &imageRes = cv::Size(-1,-1));
//! Copy constructor
CBlobContour(CBlobContour *source );
//CBlobContour(CBlobContour &source);
Expand Down Expand Up @@ -66,7 +65,7 @@ class CBlobContour

void ShiftBlobContour(int x,int y);

CvPoint GetStartPoint() const
cv::Point GetStartPoint() const
{
return m_startPoint;
}
Expand All @@ -89,7 +88,7 @@ class CBlobContour

private:
//! Starting point of the contour
CvPoint m_startPoint;
cv::Point m_startPoint;
//! All points from the contour
t_contours m_contourPoints;

Expand All @@ -98,15 +97,15 @@ class CBlobContour
//! Computed perimeter from contour
double m_perimeter;
//! Computed moments from contour
CvMoments m_moments;
cv::Moments m_moments;
static const t_PointList EMPTY_LIST;

//This value is actually used mainly in the detection part, for the labels.
CBlob* parent;
};

t_chainCode points2ChainCode(CvPoint p1, CvPoint p2);
CvPoint chainCode2Point(CvPoint origin,t_chainCode code);
t_chainCode points2ChainCode(cv::Point p1, cv::Point p2);
cv::Point chainCode2Point(cv::Point origin,t_chainCode code);

#endif //!BLOBCONTOUR_H_INCLUDED

Expand Down
Loading