OpenCV Stereo matching and disparity map - image
I am using the code sample for stereo matching that came with openCV source code, here:
/*
* stereo_match.cpp
* calibration
*
* Created by Victor Eruhimov on 1/18/10.
* Copyright 2010 Argus Corp. All rights reserved.
*
*/
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
using namespace cv;
static void print_help()
{
printf("\nDemo stereo matching converting L and R images into disparity and point clouds\n");
printf("\nUsage: stereo_match <left_image> <right_image> [--algorithm=bm|sgbm|hh|var] [--blocksize=<block_size>]\n"
"[--max-disparity=<max_disparity>] [--scale=scale_factor>] [-i <intrinsic_filename>] [-e <extrinsic_filename>]\n"
"[--no-display] [-o <disparity_image>] [-p <point_cloud_file>]\n");
}
static void saveXYZ(const char* filename, const Mat& mat)
{
const double max_z = 1.0e4;
FILE* fp = fopen(filename, "wt");
for(int y = 0; y < mat.rows; y++)
{
for(int x = 0; x < mat.cols; x++)
{
Vec3f point = mat.at<Vec3f>(y, x);
if(fabs(point[2] - max_z) < FLT_EPSILON || fabs(point[2]) > max_z) continue;
fprintf(fp, "%f %f %f\n", point[0], point[1], point[2]);
}
}
fclose(fp);
}
int main(int argc, char** argv)
{
const char* algorithm_opt = "--algorithm=";
const char* maxdisp_opt = "--max-disparity=";
const char* blocksize_opt = "--blocksize=";
const char* nodisplay_opt = "--no-display=";
const char* scale_opt = "--scale=";
if(argc < 3)
{
print_help();
return 0;
}
const char* img1_filename = 0;
const char* img2_filename = 0;
const char* intrinsic_filename = 0;
const char* extrinsic_filename = 0;
const char* disparity_filename = 0;
const char* point_cloud_filename = 0;
enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2, STEREO_VAR=3 };
int alg = STEREO_SGBM;
int SADWindowSize = 0, numberOfDisparities = 0;
bool no_display = false;
float scale = 1.f;
StereoBM bm;
StereoSGBM sgbm;
StereoVar var;
for( int i = 1; i < argc; i++ )
{
if( argv[i][0] != '-' )
{
if( !img1_filename )
img1_filename = argv[i];
else
img2_filename = argv[i];
}
else if( strncmp(argv[i], algorithm_opt, strlen(algorithm_opt)) == 0 )
{
char* _alg = argv[i] + strlen(algorithm_opt);
alg = strcmp(_alg, "bm") == 0 ? STEREO_BM :
strcmp(_alg, "sgbm") == 0 ? STEREO_SGBM :
strcmp(_alg, "hh") == 0 ? STEREO_HH :
strcmp(_alg, "var") == 0 ? STEREO_VAR : -1;
if( alg < 0 )
{
printf("Command-line parameter error: Unknown stereo algorithm\n\n");
print_help();
return -1;
}
}
else if( strncmp(argv[i], maxdisp_opt, strlen(maxdisp_opt)) == 0 )
{
if( sscanf( argv[i] + strlen(maxdisp_opt), "%d", &numberOfDisparities ) != 1 ||
numberOfDisparities < 1 || numberOfDisparities % 16 != 0 )
{
printf("Command-line parameter error: The max disparity (--maxdisparity=<...>) must be a positive integer divisible by 16\n");
print_help();
return -1;
}
}
else if( strncmp(argv[i], blocksize_opt, strlen(blocksize_opt)) == 0 )
{
if( sscanf( argv[i] + strlen(blocksize_opt), "%d", &SADWindowSize ) != 1 ||
SADWindowSize < 1 || SADWindowSize % 2 != 1 )
{
printf("Command-line parameter error: The block size (--blocksize=<...>) must be a positive odd number\n");
return -1;
}
}
else if( strncmp(argv[i], scale_opt, strlen(scale_opt)) == 0 )
{
if( sscanf( argv[i] + strlen(scale_opt), "%f", &scale ) != 1 || scale < 0 )
{
printf("Command-line parameter error: The scale factor (--scale=<...>) must be a positive floating-point number\n");
return -1;
}
}
else if( strcmp(argv[i], nodisplay_opt) == 0 )
no_display = true;
else if( strcmp(argv[i], "-i" ) == 0 )
intrinsic_filename = argv[++i];
else if( strcmp(argv[i], "-e" ) == 0 )
extrinsic_filename = argv[++i];
else if( strcmp(argv[i], "-o" ) == 0 )
disparity_filename = argv[++i];
else if( strcmp(argv[i], "-p" ) == 0 )
point_cloud_filename = argv[++i];
else
{
printf("Command-line parameter error: unknown option %s\n", argv[i]);
return -1;
}
}
if( !img1_filename || !img2_filename )
{
printf("Command-line parameter error: both left and right images must be specified\n");
return -1;
}
if( (intrinsic_filename != 0) ^ (extrinsic_filename != 0) )
{
printf("Command-line parameter error: either both intrinsic and extrinsic parameters must be specified, or none of them (when the stereo pair is already rectified)\n");
return -1;
}
if( extrinsic_filename == 0 && point_cloud_filename )
{
printf("Command-line parameter error: extrinsic and intrinsic parameters must be specified to compute the point cloud\n");
return -1;
}
int color_mode = alg == STEREO_BM ? 0 : -1;
Mat img1 = imread(img1_filename, color_mode);
Mat img2 = imread(img2_filename, color_mode);
if( scale != 1.f )
{
Mat temp1, temp2;
int method = scale < 1 ? INTER_AREA : INTER_CUBIC;
resize(img1, temp1, Size(), scale, scale, method);
img1 = temp1;
resize(img2, temp2, Size(), scale, scale, method);
img2 = temp2;
}
Size img_size = img1.size();
Rect roi1, roi2;
Mat Q;
if( intrinsic_filename )
{
// reading intrinsic parameters
FileStorage fs(intrinsic_filename, CV_STORAGE_READ);
if(!fs.isOpened())
{
printf("Failed to open file %s\n", intrinsic_filename);
return -1;
}
Mat M1, D1, M2, D2;
fs["M1"] >> M1;
fs["D1"] >> D1;
fs["M2"] >> M2;
fs["D2"] >> D2;
M1 *= scale;
M2 *= scale;
fs.open(extrinsic_filename, CV_STORAGE_READ);
if(!fs.isOpened())
{
printf("Failed to open file %s\n", extrinsic_filename);
return -1;
}
Mat R, T, R1, P1, R2, P2;
fs["R"] >> R;
fs["T"] >> T;
stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );
Mat map11, map12, map21, map22;
initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);
Mat img1r, img2r;
remap(img1, img1r, map11, map12, INTER_LINEAR);
remap(img2, img2r, map21, map22, INTER_LINEAR);
img1 = img1r;
img2 = img2r;
}
numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : ((img_size.width/8) + 15) & -16;
bm.state->roi1 = roi1;
bm.state->roi2 = roi2;
bm.state->preFilterCap = 31;
bm.state->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 9;
bm.state->minDisparity = 0;
bm.state->numberOfDisparities = numberOfDisparities;
bm.state->textureThreshold = 10;
bm.state->uniquenessRatio = 15;
bm.state->speckleWindowSize = 100;
bm.state->speckleRange = 32;
bm.state->disp12MaxDiff = 1;
sgbm.preFilterCap = 63;
sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
int cn = img1.channels();
sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.minDisparity = 0;
sgbm.numberOfDisparities = numberOfDisparities;
sgbm.uniquenessRatio = 10;
sgbm.speckleWindowSize = bm.state->speckleWindowSize;
sgbm.speckleRange = bm.state->speckleRange;
sgbm.disp12MaxDiff = 1;
sgbm.fullDP = alg == STEREO_HH;
var.levels = 3; // ignored with USE_AUTO_PARAMS
var.pyrScale = 0.5; // ignored with USE_AUTO_PARAMS
var.nIt = 25;
var.minDisp = -numberOfDisparities;
var.maxDisp = 0;
var.poly_n = 3;
var.poly_sigma = 0.0;
var.fi = 15.0f;
var.lambda = 0.03f;
var.penalization = var.PENALIZATION_TICHONOV; // ignored with USE_AUTO_PARAMS
var.cycle = var.CYCLE_V; // ignored with USE_AUTO_PARAMS
var.flags = var.USE_SMART_ID | var.USE_AUTO_PARAMS | var.USE_INITIAL_DISPARITY | var.USE_MEDIAN_FILTERING ;
Mat disp, disp8;
//Mat img1p, img2p, dispp;
//copyMakeBorder(img1, img1p, 0, 0, numberOfDisparities, 0, IPL_BORDER_REPLICATE);
//copyMakeBorder(img2, img2p, 0, 0, numberOfDisparities, 0, IPL_BORDER_REPLICATE);
int64 t = getTickCount();
if( alg == STEREO_BM )
bm(img1, img2, disp);
else if( alg == STEREO_VAR ) {
var(img1, img2, disp);
}
else if( alg == STEREO_SGBM || alg == STEREO_HH )
sgbm(img1, img2, disp);
t = getTickCount() - t;
printf("Time elapsed: %fms\n", t*1000/getTickFrequency());
//disp = dispp.colRange(numberOfDisparities, img1p.cols);
if( alg != STEREO_VAR )
disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
else
disp.convertTo(disp8, CV_8U);
if( !no_display )
{
namedWindow("left", 1);
imshow("left", img1);
namedWindow("right", 1);
imshow("right", img2);
namedWindow("disparity", 0);
imshow("disparity", disp8);
printf("press any key to continue...");
fflush(stdout);
waitKey();
printf("\n");
}
if(disparity_filename)
imwrite(disparity_filename, disp8);
if(point_cloud_filename)
{
printf("storing the point cloud...");
fflush(stdout);
Mat xyz;
reprojectImageTo3D(disp, xyz, Q, true);
saveXYZ(point_cloud_filename, xyz);
printf("\n");
}
return 0;
}
And I have tried all of the algorithms on the following set of images:
http://imageshack.com/a/img607/4641/utam.jpg (left)
http://imageshack.com/a/img62/5939/2hkc.jpg (right)
Here is my result:
http://imageshack.com/a/img856/4274/1n50.jpg
And here is the desired result:
http://i.stack.imgur.com/W9PBr.jpg
What could be the problem?
change parameters! For example, say bm, my experience is SADWindowSize and minDisparity really matters a lot! so you can add trackbars for each parameter and play with it until you get desired result. I've tried the same pair of images and it works fine. So all you need to do it try, try and try parameters.
I know it sounds crazy, but I had similar output when I was accidentally passing the same image as both the left and right input to the SGBMStereo algorithm. Just taking a shot in the dark...
Related
Segmentation fault is on terminal. Its the code to convert string to binary tree
Node * create(Node * root, int I, int J, string str) { if (I == J) { root -> data =str[I]; root -> left=NULL; root -> right=NULL; } int i = 0, j = 0, k = 0, l = 0; //// to store the data of root string val; for (i = I; i < J; i++) { if (str[i] == '(') break; val.push_back(str[i]); } root -> data = stoi(val); stack < char > st; for (j = i; j < J; j++) { if (str[j] == '(') st.push(str[j]); else if (str[j] == ')') st.pop(); if (st.empty()) break; } for (l = j + 1; l < J; l++) { if (str[l] == '(') st.push(str[l]); else if (str[l] == ')') st.pop(); if (st.empty()) break; } k = j + 1; if (j - i == 2) root -> left -> data = str[i + 1]; else root -> left = create(root -> left, i + 1, j - 1, str); if (l == k) root -> right=NULL; else if (l - k == 2) root -> right -> data = str[k + 1]; else root -> right = create(root -> right, k + 1, l - 1, str); return root; } Node * treeFromString(string str){ Node * p = create(p, 0, str.size() - 1, str); return p; } Here I have initialized variables i , j , k , l to track the left child and right child bracket in the string. I , J are the range of the node for a particular activation record of recursion.
I assume you parsed some expression, by your code I pre-implemented it. I just implement build a tree for following expression: expression: |<symbol>| <integer> '(' <expression> ')' '('<expression>')' symbol : any C++ `char` single byte character. integer : any C++ valid int type value. #include <iostream> #include <string> #include <string_view> // C++17 std::string_view #include <charconv> // C++17 std::from_chars. #include <cassert> //simulate Node class struct Node { Node *left, *right; int data; }; //1. use string_view instead of triple I, J, std::string. //2. First argument Node* root - needn't. It should be local variable. Node * create(std::string_view str) { assert(!str.empty()); if (str.size() == 1) { Node* root = new Node; //-> YOU should allocate a memory for root. root -> data =str[0]; root -> left=nullptr; // use nullptr instead of NULL for c++11 or later. root -> right=nullptr; return root; // exit needed! } Node* root = new Node; root->left = nullptr; root->right = nullptr; root->data = 0; //// to store the data of root //2. THERE NEED take an integer until first '(' symbol. { std::size_t i = 0; while (i < str.size() && str[i] != '(' ) ++i; // str[0 .. i) - interval is an integer. int val = 0; (void)std::from_chars(str.data(), str.data() + i, val); // FOR simplifity don't check validness of conversation. str.remove_prefix(i); root->data = val; } //3. SKIP balanced '(' and ')' /*stack < char > st; for (j = i; j < J; j++) { if (str[j] == '(') st.push(str[j]); else if (str[j] == ')') st.pop(); if (st.empty()) break; } * */ /** we can implement it another way */ assert(!str.empty() && str[0] == '(' ); std::string_view within_bracket; { int balanced_brackets = 0; std::size_t i = 0; while (i < str.size()) { if (str[i] == '(') ++ balanced_brackets; else if (str[i] == ')' ) --balanced_brackets; i++; if (balanced_brackets == 0) break; } assert (i > 0 && str[ i - 1 ] == ')' ); // 0 1 2 3 // str[0..i) - is '(' ... ')' symbols. within_bracket = std::string_view(str.data() + 1, i - 2); str.remove_prefix(i); } /****4. THIS second balanced bracket check */ std::string_view second_within_bracket; /* for (l = j + 1; l < J; l++) { if (str[l] == '(') st.push(str[l]); else if (str[l] == ')') st.pop(); if (st.empty()) break; } k = j + 1; */ assert(!str.empty() && str[0] == '(' ); // ========== second balanced brackets check ========== { std::size_t i = 0; int balanced_brackets = 0; while (i < str.size()) { if (str[i] == '(') ++ balanced_brackets; else if (str[i] == ')' ) --balanced_brackets; i++; if (balanced_brackets == 0) break; } // 0 1 2 3 // str[0..i) - is '(' ... ')' symbols. second_within_bracket = std::string_view(str.data() + 1, i - 2); str.remove_prefix(i); } //================================ /* if (j - i == 2) root -> left -> data = str[i + 1]; else root -> left = create(i + 1, j - 1, str); if (l == k) root -> right=NULL; else if (l - k == 2) root -> right -> data = str[k + 1]; else root -> right = create(root -> right, k + 1, l - 1, str); */ root->left = create(within_bracket); root->right = create(second_within_bracket); return root; } Node * treeFromString(std::string_view str){ Node * p = create(str); return p; } void printTree(Node* root, int level = 0) { if (root==nullptr) return; for (int i= 0; i < level; ++i) std::cout << "--"; std::cout << " data = " << root->data << std::endl; printTree(root->left, level + 1); printTree(root->right, level + 1); } int main(){ std::string str = "12(8(7)(5))(9(3)(2(1)(8)))"; Node * expr = treeFromString(str); printTree(expr); } godbold output: Program returned: 0 data = 12 -- data = 8 ---- data = 55 ---- data = 53 -- data = 9 ---- data = 51 ---- data = 2 ------ data = 49 ------ data = 56
This answer is a bit different, it assumes you are loading a tree of integer values from a string, that could be loaded from a file. Next time you ask a question about code, could you please explain a little bit what the code does? Guessing does take some time and some effort. I've reused the main() and PrintTree() functions from Khurshid Normuradov's answer. I hope he won't mind. I took the liberty to add modern c++ coding techniques because this question is tagged c++17, so you're getting an example in c++17. #include <algorithm> #include <iostream> #include <memory> #include <string> #include <string_view> struct Node { std::unique_ptr<Node> left = nullptr; std::unique_ptr<Node> right = nullptr; int value = 0; }; std::unique_ptr<Node> treeFromString(std::string_view str) { std::cout << "treeFromString(\"" << str << "\")\n"; if (str.empty()) return {}; auto node = std::make_unique<Node>(); // extract an int auto pos = str.find_first_not_of("0123456789"); auto val = str.substr(0, pos); // optional: std::stoi() would throw anyway in this case if (val.empty()) throw std::runtime_error("invalid value in expression"); node->value = std::stoi(std::string{val}); if (val.length() == str.length()) return node; str = str.substr(val.length()); // Both left/right parsing are similar and use this // common subroutine. // expects parens delimited string as input. // param str in: str string to parse from // out: whatever's left to parse // returns string content within parens, parens not included. auto extract_parens_contents = [](std::string_view& str) { // right here would be the perfect place to insert code to skip // whitespace if you ever needed to do that. // find parens extent int parens = 0; auto parens_end = std::find_if(str.begin(), str.end(), [&parens](char c) { parens += (c == '(') - (c == ')'); return (parens == 0); }); if (parens_end == str.end()) throw std::runtime_error("unbalanced parens in expression"); // extract result auto result = std::string_view( str.begin() + 1, std::distance(str.begin() + 1, parens_end)); // remove spent bytes from input stream str = std::string_view( parens_end + 1, str.length() - std::distance(str.begin(), parens_end + 1)); return result; }; node->left = treeFromString(extract_parens_contents(str)); node->right = treeFromString(extract_parens_contents(str)); return node; } // special thanks to user Khurshid Normuradov, who originally wrote the two functions below. // it would be difficult to writing something that would be any better for the // intended purpose. void printTree(Node* root, int level = 0) { if (root == nullptr) return; for (int i = 0; i < level; ++i) std::cout << "--"; std::cout << " data = " << root->value << std::endl; printTree(root->left.get(), level + 1); printTree(root->right.get(), level + 1); } int main() { std::string str = "12(8(7)(5))(9(3)(2(1)(8)))"; auto expr = treeFromString(str); printTree(expr.get()); } You can play with the code here: https://godbolt.org/z/ch3zv5KTT
Reading EXR file
I'm trying to create a IWICBitmap from an EXR file (error checks removed). #pragma pack(push,1) struct fl { float r, g, b, a; }; #pragma pack(pop) HRESULT Open(const char* f,IWICBitmap** d) { exr_context_initializer_t ctxtinit = EXR_DEFAULT_CONTEXT_INITIALIZER; exr_context_t myfile = {}; exr_result_t rv = exr_start_read(&myfile, f, &ctxtinit); int part_index = 0; const exr_attr_chlist_t* chl = 0; exr_get_channels(myfile, part_index, &chl); int32_t ck = 0; rv = exr_get_chunk_count(myfile, part_index, &ck); int32_t sl = 0; rv = exr_get_scanlines_per_chunk(myfile, part_index, &sl); int y = 0; int wi = 0; int he = 0; std::vector<fl> data; // put here the floats exr_decode_pipeline_t dec = {}; for (int32_t cuk = 0; cuk < ck; cuk++) { exr_chunk_info_t ch = {}; exr_read_scanline_chunk_info(myfile, part_index, y, &ch); wi = ch.width; he += ch.height; y += sl; bool first = 0; if (dec.decompress_fn == 0) { rv = exr_decoding_initialize(myfile, part_index, &ch, &dec); rv = exr_decoding_choose_default_routines(myfile, part_index, &dec); first = 1; } if (!first) rv = exr_decoding_update(myfile, part_index,&ch,&dec); rv = exr_decoding_run(myfile, part_index, &dec); int NumPixels = (wi * ch.height); auto BytesPerPixel = ch.unpacked_size / NumPixels; if (true) { // RGB(A) if (chl->entries[0].pixel_type == EXR_PIXEL_HALF) { if (BytesPerPixel == chl->num_channels * 2) { auto ds = data.size(); data.resize(ds + NumPixels); auto p = data.data() + ds; char* x = (char*)dec.unpacked_buffer; for (int j = 0; j < NumPixels; j++) { uint16_t* u = (uint16_t*)x; p->a = 1.0f; for (int jH = 0; jH < chl->num_channels; jH++) { half ha(Imath_3_2::half::FromBits,*u); ha.setBits(*u); if (strcmp(chl->entries[jH].name.str, "R") == 0) p->r = ha.operator float(); if (strcmp(chl->entries[jH].name.str, "G") == 0) p->g = ha.operator float(); if (strcmp(chl->entries[jH].name.str, "B") == 0) p->b = ha.operator float(); if (strcmp(chl->entries[jH].name.str, "A") == 0) p->a = ha.operator float(); u++; } x += BytesPerPixel; p++; } } else break; } if (chl->entries[0].pixel_type == EXR_PIXEL_FLOAT) { // code removed for simplicity, I guess the same issue happens here unless it's a problem of the half-float } } } rv = exr_decoding_destroy(myfile, &dec); exr_finish(&myfile); CComPtr<IWICImagingFactory2> wbfact = 0; CoCreateInstance(CLSID_WICImagingFactory2, 0, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory2), (void**)&wbfact); return wbfact->CreateBitmapFromMemory(wi, he, GUID_WICPixelFormat128bppPRGBAFloat, wi * 16,(UINT)data.size()*16, (BYTE*)data.data(), d); } What am I doing wrong? The pixel number I'm reading is correct (in this image 800x800). My result: Photoshop: Is there a problem with the half-float? I'm just using the OpenEXR's IMath implementation.
Why is child process not executed?
So I have two identical files representing a matrix : 4x3 1 2 3 1 2 3 1 2 3 1 2 3 I have to sum the two matrix , but I have to use processe in which each process is responsible for calculating each column of the matrix. I have this : int addmx(const char *file1, const char *file2){ FILE *f1 = fopen(file1,"r"); if (f1 == NULL){ perror("Error in opening file 1"); return -1; } FILE *f2 = fopen (file2, "r"); if (f2 == NULL){ perror("Error in opening file 2"); return -1; } struct stat sb; if (fstat(fileno(f1),&sb) == -1){ perror("Couldn't get file size.\n"); } printf("The file size is %ld\n",sb.st_size); struct stat sb2; if (fstat(fileno(f2),&sb2) == -1){ perror("Couldn't get file size.\n"); } printf("The file size is %ld\n",sb2.st_size); char *file_in_memory = mmap(NULL,sb.st_size ,PROT_READ ,MAP_SHARED,fileno(f1),0); char *file_in_memory2 = mmap(file_in_memory,sb2.st_size,PROT_READ,MAP_SHARED,fileno(f2),0); char *file_in_memory3 = mmap(file_in_memory2,sb.st_size ,PROT_WRITE,MAP_SHARED,0,0); for (int i = 0; i < sb.st_size;i++){ printf("%c",file_in_memory[i]); } printf("\n"); for (int i = 0; i < sb2.st_size;i++){ printf("%c",file_in_memory2[i]); } int counter = 1; char ch1; do { ch1 = fgetc(f1); if (ch1 == '\n'){ break; } else counter++; } while(1); unsigned int row = atoi(&file_in_memory[0]) ; unsigned int col = atoi(&file_in_memory[2]) ; //file_in_memory3[0] = row + '0'; file_in_memory3[1] = 'x'; file_in_memory3[2] = col + '0'; pid_t pid_matrix[col]; for (size_t i = 1; i <= col;i++) { pid_matrix[col] = fork(); if (pid_matrix[col] == -1) { //erro } else if (pid_matrix[col] == 0) { //child process for (int j = 1; j <= row;j++){ int new_col = atoi(&file_in_memory[counter + (j-1)*(col*2) + ((i-1)*2)] )+ atoi(&file_in_memory2[counter + (j-1)*(col*2) + ((i-1)*2)]); file_in_memory3[counter+ (j-1)*(col*2) + ((i-1)*2)] = new_col + '0'; printf("%d\n",new_col); } printf("Child process with pid %d for column %d\n", getpid(),i); exit(EXIT_SUCCESS); } else { //parent process printf("Created a new process with pid %d\n", pid_matrix[col]); } } for ( int i = 0; i < sb.st_size;i++){ printf("%c",file_in_memory3[i]); } munmap(file_in_memory,sb.st_size); munmap(file_in_memory2,sb2.st_size); close(f1); close(f2); return 0; } However, the child processes are not executing ( because it is not printing "Child process with pid ... ") but when I remove the line of code : "file_in_memory3[counter + (j-1)(col2) + ((i-1)*2)] = new_col + '0';" the child processes actually execute...
Special minimum spanning tree
There is a node that can only get one line, I use both kruskal and prim, but the judger said TLE(Time Limit Exceed). Then I will describe the question. There are many computers, we need to connect all of them, we give the cost of connection between different computers, also we give the special number of computer which can be only connected by one line. Finally, we guarantee there is a answer and there is no Self-Loop, but there may have multiple edge which have different weight between same node. Here is my kruskal code, it's TLE. #include <iostream> #include <algorithm> using namespace std; typedef struct edge{ int start; int end; int weight; }Edge; int special = 0; int edgenum; Edge _edge[600005]; int i, j, k; int counter = 0; bool Cmp(const edge &a, const edge &b){ return a.weight < b.weight; } int getEnd(int vends[], int i){ while(vends[i] != 0) i = vends[i]; return i; } void kruskal(){ int p1, p2, m, n, ans = 0; int vends[10005] = {0}; sort(_edge, _edge+counter, Cmp); for(i = 0; i < edgenum; ++i){ p1 = _edge[i].start; p2 = _edge[i].end; if ((p1 == k || p2 == k) && special) continue; m = getEnd(vends, p1); n = getEnd(vends, p2); if(m != n){ if (p1 == k || p2 == k) special = 1; vends[m] = n; ans += _edge[i].weight; } } cout << ans << endl; } int main(){ int n, m; cin >> n >> m >> k; edgenum = m; while(m--){ int a, b, c; cin >> a >> b >> c; _edge[counter].start = a; //Get the Edge _edge[counter].weight = c; _edge[counter++].end = b; // _edge[counter].start = b; // _edge[counter].weight = c; // _edge[counter++].end = a; } kruskal(); } Here is my Prim, but also TLE: #include <iostream> using namespace std; typedef char VertexType; typedef struct node{ int adjvex = 0; int weight = INT32_MAX; struct node *next = NULL; }Node; typedef struct vnode{ VertexType data; Node *firstnode = NULL; }Vnode; Vnode node[10005]; int VNUM; int n, m, k; int lowcost[10005] = {0}; int addvnew[10005]; //未加入最小生成树表示为-1,加入则为0 int adjecent[10005] = {0}; bool is_special = false; int flag; void prim(int start){ long long sumweight = 0; int i, j; Node *p = node[start].firstnode; for (i = 1; i <= VNUM; ++i) { //重置 addvnew[i] = -1; } while (p->next != NULL){ if (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex]) lowcost[p->adjvex] = p->weight; p = p->next; } if (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex]) lowcost[p->adjvex] = p->weight; addvnew[start] = 0; // adjecent[start] = start; if (start == k) { is_special = true; flag = 1; } for (i = 1; i < VNUM; ++i) { int min = INT32_MAX; int v=-1; for (j = 1; j <= VNUM; ++j) { //Find the min if (addvnew[j] == -1 && lowcost[j] < min && lowcost[j] != 0){ min = lowcost[j]; v = j; } } if (v != -1){ //if min is found if (flag == 1){ for (int l = 0; l < 10005; ++l) { lowcost[l] = 0; } flag = 0; } addvnew[v] = 0; sumweight += min; p = node[v].firstnode; while(p->next != NULL){ if (is_special && p->adjvex == k){ //If find the special node p = p->next; continue; } if(addvnew[p->adjvex] == -1 && (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex])){ //如果该点未连接 lowcost[p->adjvex] = p->weight; } p = p->next; } if (!(is_special && p->adjvex == k)) if(addvnew[p->adjvex] == -1 && (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex])){ lowcost[p->adjvex] = p->weight; } } } cout << sumweight << endl; } int main(){ cin >> n >> m >> k; VNUM = n; while (m--){ int a, b, c; cin >> a >> b >> c; Node *p = (Node*)malloc(sizeof(Node)); p->adjvex = b; p->weight = c; p->next = node[a].firstnode; node[a].firstnode = p; Node *q = (Node*)malloc(sizeof(Node)); q->adjvex = a; q->weight = c; q->next = node[b].firstnode; node[b].firstnode = q; } prim(k); } I don't know how to modify the both code, I try my best, thank you
fast algorithm for move to front transform
I'm trying to find the fastest algorithm for the move to front transformation. The one that's used for example in conjunction with burrows wheeler transform. The best I've managed so far does about 15MB/s on Core i3 2.1GHz. But I'm sure that it's not optimal. Here's my best effort so far. Is there anything that's faster? class mtf256_x { typedef unsigned char u8; typedef unsigned long long L; public: L enc[37]; u8 dec[256]; mtf256_x() { unsigned i; for (i=0;i<37;i++) { enc[i]=0; } for (i=0;i<256;i++) { dec[i]=i; set(i,i); } } u8 decode(u8 in) { u8 r = dec[in]; if (in) { memmove(dec+1,dec,in); dec[0]=r; } return r; } u8 set(unsigned x, u8 y) { unsigned xl = (x%7)*9; unsigned xh = (x/7); enc[xh] &= ~(0x1FFLLU<<xl); enc[xh] |= ((L)y)<<xl; } u8 get(unsigned x) { return enc[x/7] >> (x%7)*9; } u8 encode(u8 in) { u8 r; unsigned i; r = get(in); L m2 = 0x0040201008040201LLU; // 0x01 for each 9 bit int L m1 = 0x3FDFEFF7FBFDFEFFLLU; // 0xff for each 9 bit int L Q = (0x100+r)*m2; L a,b,c,d; L * l= enc; for (i=0;i<37;i++) { a=l[i]; a+= ((Q-a)>>8)&m2; // conditional add 1 a&=m1; l[i]=a; } set(in,0); return r; } };
Maybe you can try this http://kuc406.moxo.cz/projects.php int b[ uint8Max + 2 ], treshold = 0, pivot = -1; long inFileOffst = 0, pOffset = 0, t[ uint8Max + 1 ]; int rank, c, i, p0, p1; // initialise list for( i = 0; i <= uint8Max; t[ i++ ] = 0 ); for( i = 1; i <= uint8Max; b[ i - 1 ] = i++ ); b[ uint8Max ] = b[ uint8Max + 1 ] = 0; // read data // input = c; output = rank inFileOffst++; rank = 0; if( ( p1 = b[uint8Max + 1] ) != ( c = data[input] ) ) { if( t[ c ] < pOffset ) { rank += treshold++; t[ c ] = inFileOffst; p1 = pivot; } else if( t[ c ] == pOffset ) { pivot = c; t[ c ] = pOffset = inFileOffst; treshold = 0; } while( true ) // passing the list { if( ( p0 = b[ p1 ] ) == c ) { rank++; b[ p1 ] = b[ c ]; break; } if( ( p1 = b[ p0 ] ) == c ) { rank += 2; b[ p0 ] = b[ c ]; break; } if( ( p0 = b[ p1 ] ) == c ) { rank += 3; b[ p1 ] = b[ c ]; break; } if( ( p1 = b[ p0 ] ) == c ) { rank += 4; b[ p0 ] = b[ c ]; break; } rank += 4; } b[ c ] = b[ uint8Max + 1 ]; b[ uint8Max + 1 ] = c; } But it's more like for a smal alphabet (e.g. for the bytes), but for bigger alphabet, I'd suggest to try nburns version, or more at http://encode.ru forum.