Please i have many problem with "parallel_for_" ( random segmentation fault). in the majority of cases, the code works but sometimes it displays segmentation error (random). I use parallel_for_ with opencv 3.1.0. My code is attached
class Paralleltextzone : public ParallelLoopBody
{ public: Paralleltextzone (vector <string> &_liste_files, const Mat &_mask_base, int _mask_debug, const char* _debug_path, vector<float> &_param_image) :liste_files(_liste_files), mask_base(_mask_base), mask_debug (_mask_debug), debug_path (_debug_path), param_image (_param_image) { } virtual void operator ()(const Range& range) const { for (int r = range.start; r < range.end; r++)
{ int resl=0;
//get text zone
cout<<"Processing the frame: "<<r<<endl;
Mat output_mat, mask, Kernel, boxFilter;
string image_name=liste_files.at(r);
Mat image=imread(image_name);
threshold(mask_base,mask, 10, 255, cv::THRESH_BINARY);
resize(mask_base,mask_base,image.size());
image.copyTo(output_mat, mask_base);
//save result
if (mask_debug)
{
//char temp=to_string(r)+"_textzone.png";
char result_name [100];
char buffer [50];
sprintf (buffer,debug_path, "textzon_%d.png", r);
strcpy(result_name,buffer);
imwrite( result_name,output_mat);
}
//text recongiton
Kernel = Mat::zeros( 9, 9, CV_32F );
Kernel.at<float>(4,4) = 2.0;
boxFilter=Mat::ones( 9, 9, CV_32F )/81.0;
Kernel=Kernel-boxFilter;
filter2D(output_mat, output_mat, -1 , Kernel );
resl=text_recognition(output_mat, output_mat.rows, output_mat.cols, r, 0, "/home/krayni/Bureau/VTT/TextDetect/txt", 0, (double)param_image.at(0), (double)param_image.at(1), (int) param_image.at(2), (int)param_image.at(3),(int)param_image.at(4));
}
}
Paralleltextzone& operator=(const Paralleltextzone &) {
return *this;
};
my principal function is
/*Text Regions Detection*/
extern "C" int text_recognition(Mat &image_orig, int rows, int cols, int stime, int Debug, const char *tempPath, int MULTI_CHANNEL, double alpha, double beta, int hue, int sat, int level) {
Mat grey;
Mat image_processed = Mat::zeros(image_orig.size()*3, image_orig.type());
prepare_image_for_ocr1(image_orig, image_processed, alpha, beta); // enhance image contrast and brighteness
vector<Mat> channels(2);
vector<vector<ERStat> > regions(2);
cvtColor(image_processed, grey,COLOR_RGB2GRAY);
//channels.clear();
channels.push_back(grey);
channels.push_back(255-grey);
regions[0].clear();
regions[1].clear();
vector< Ptr<ERFilter> > er_filters1;
vector< Ptr<ERFilter> > er_filters2;
Ptr<ERFilter> er_filter1 = createERFilterNM1(loadClassifierNM1("trained_classifierNM1.xml"),8,0.00015f,0.13f,0.2f,true,0.1f);
Ptr<ERFilter> er_filter2 = createERFilterNM2(loadClassifierNM2("trained_classifierNM2.xml"),0.5);
// Create ERFilter objects with the 1st and 2nd stage default classifiers
for (int i=0; i<2; i++)
{
//Ptr<ERFilter> er_filter1 = createERFilterNM1(loadClassifierNM1("/opt/exe/ASAP_TraitementPTT_python/trained_classifierNM1.xml"),8,0.00015f,0.13f,0.2f,true,0.1f);
//Ptr<ERFilter> er_filter2 = createERFilterNM2(loadClassifierNM2("/opt/exe/ASAP_TraitementPTT_python/trained_classifierNM2.xml"),0.5);
er_filters1.push_back(er_filter1);
er_filters2.push_back(er_filter2);
}
// Apply the default cascade classifier to each independent channel (could be done in parallel)
Extractfeatures extractfeatures(channels,regions,er_filters1,er_filters2);
parallel_for_(cv::Range(0,2), extractfeatures);
//
//vector<vector<ERStat> > regions(channels.size());
/*
for (int c=0; c<(int)channels.size(); c++)
{
er_filter1->run(channels[c], regions[c]);
er_filter2->run(channels[c], regions[c]);
}
*/
// If debug mode save debugging images
if (Debug) { std::string str(tempPath); boost::filesystem::path dir(str); if (!(boost::filesystem::exists(dir))) { cout << "Debug folder not found..."<< endl; cout << "Creating the debug folder.."<< str << endl; boost::filesystem::create_directory(dir); } // Draw the detected ExtremeRegions Mat out_img_decomposition= Mat::zeros(image_processed.rows+2, image_processed.cols+2, CV_8UC1); vector<vec2i> tmp_group; for (int i=0; i<(int)regions.size(); i++) { for (int j=0; j<(int)regions[i].size();j++) { tmp_group.push_back(Vec2i(i,j)); } Mat tmp= Mat::zeros(image_processed.rows+2, image_processed.cols+2, CV_8UC1); er_draw(channels, regions, tmp_group, tmp); if (i > 0) tmp = tmp / 2; out_img_decomposition = out_img_decomposition | tmp; tmp_group.clear(); }
char file_name[1024];
sprintf(file_name, "%s/image_orig%d.jpg", tempPath, stime);
imwrite(file_name, image_orig);
sprintf(file_name, "%s/image_processed%d.jpg", tempPath, stime);
imwrite(file_name, image_processed);
sprintf(file_name, "%s/out_img_decomposition%d.jpg", tempPath, stime);
imwrite(file_name, out_img_decomposition);
}
// Merge character groups
vector< vector<Vec2i> > nm_region_groups;
vector<Rect> nm_boxes;
erGrouping(image_processed, channels, regions, nm_region_groups, nm_boxes, ERGROUPING_ORIENTATION_HORIZ);
// Remove too little isolated regions
for (int i=0; i<(int)nm_boxes.size(); i++)
{
float ratio = (float) nm_boxes[i].height/nm_boxes[i].width;
int height = nm_boxes[i].height;
if (((ratio < 0.11) && (height < 14)) || (height <= 12))
{
nm_boxes.erase(nm_boxes.begin()+i);
i--;
}
}
// Merge overlapping text regions
bool foundIntersection = false;
do
{
foundIntersection = false;
for (int i=0; i<(int)nm_boxes.size(); i++)
{
Rect current = nm_boxes[i];
for (int j=i+1; j<(int)nm_boxes.size(); j++)
{
Rect inter = current & nm_boxes[j]; //compute the rectangles intersection
if (inter.area() > 0)
{
foundIntersection = true;
Rect uni = nm_boxes[i] | nm_boxes[j]; //compute the rectangles union
current = uni & Rect(0,0,image_processed.cols, image_processed.rows); // To avoid a rectangle getting out of the image
nm_boxes.erase(nm_boxes.begin()+j);
nm_boxes.at(i) = current;
j--;
}
}
}
} while (foundIntersection);
if (Debug)
{
Mat rectangles;
char file_name_[1024];
image_processed.copyTo(rectangles);
for (int i=0; i<(int)nm_boxes.size(); i++)
{
rectangle(rectangles, nm_boxes[i].tl(), nm_boxes[i].br(), Scalar(255,0,255), 2);
float ratio = (float) nm_boxes[i].height/nm_boxes[i].width;
sprintf(file_name_, "%s/rectangles_%d.jpg", tempPath, stime);
imwrite(file_name_,rectangles );
}
}
// Enlarge text zones to include border characters:
for (int i=0; i<(int)nm_boxes.size(); i++)
{
cv::Point inflationPoint(-5,-5);
cv::Size inflationSize(10,10);
nm_boxes[i] += inflationPoint;
nm_boxes[i] += inflationSize;
nm_boxes[i] = nm_boxes[i] & Rect(0,0,image_processed.cols, image_processed.rows); // To avoid a rectangle getting out of the image
}
//imshow("a",image_processed);
// Merge the different text zones in one single image to pass to the OCR and store it on the disk
if (nm_boxes.size()!=0)
{
Mat merge;
merge_text_zones_ocr(image_processed, merge, nm_boxes, stime, tempPath, hue, sat, level);
char file_name_merged[1024];
sprintf(file_name_merged, "%s/merged_%d.png", tempPath, stime );
imwrite(file_name_merged, merge);
char command[1024];
sprintf(command, "convert %s/merged_%d.png -resample 300 %s/merged_%d.png" , tempPath, stime, tempPath, stime);
system(command);
}
// Free memory
// memory clean-up er_filter1.release(); er_filter2.release(); er_filters2.clear(); er_filters1.clear(); channels.clear(); //regions.clear();
if (!nm_boxes.empty())
{
nm_boxes.clear();
}
return 1;
}