int main(){ std::vector<int> intdata(0); std::vector<float> floatdata(0); std::vector<std::vector <float>> floatmatrix(0); for(size_t i=0; i<100; i++){ intdata.push_back(i); floatdata.push_back((float)10.0*i); } for(size_t j=0; j<55; j++){ floatmatrix.push_back(floatdata); } IGORdata::write_itx<int>(intdata, "intdata.itx", "intdata"); IGORdata::write_ibw_onedim_double(intdata, intdata.size(), "intdata.ibw", "intdata_ibw"); // IGORdata:: }
void colorengine::threadFunc() { std::unique_ptr<float> regdata(new float[width_*height_]); std::vector<float> scalar_constant(3); scalar_constant.push_back(0); scalar_constant.push_back(0); scalar_constant.push_back(0); _XTIFFInitialize(); rawdata_tiff = TIFFOpen(raw_tiff_path.c_str(), "w"); TIFFSetField(rawdata_tiff, TIFFTAG_NFILTERS, filter_->nfilters()); TIFFSetField(rawdata_tiff, TIFFTAG_NLIGHTS, nlights_); for (auto filter_index = 0; filter_index < filter_->nfilters(); ++filter_index) { std::vector<float> cmf = filter_->cmfValues(filter_->wavelengthAtPos(filter_index)); float illuminant = filter_->illuminantValue(filter_->wavelengthAtPos(filter_index)); for (auto xyz_index = 0; xyz_index < 3; ++xyz_index) { scalar_constant[xyz_index] += cmf[xyz_index] * illuminant; } } int page_index = 0; for (int filter_index = 0; filter_index < filter_->nfilters(); ++filter_index) { for (int light_index = 0; light_index < nlights_; ++light_index) { std::shared_ptr<unsigned short> data = data_queue_.pop(); if (cancel_) { return; } std::unique_ptr<float> floatdata(new float[width_*height_]); for (auto y = 0; y < height_; ++y) { for (auto x = 0; x < width_; ++x) { if (data.get()[y*width_+x] - bias_data.get()[y*width_+x] < 0) { data.get()[y*width_+x] = 0; } else { data.get()[y*width_+x] -= bias_data.get()[y*width_+x]; } } } for (auto y = 0; y < height_; ++y) { for (auto x = 0; x <width_; ++x) { if (flat_data[light_index]->filterData(filter_index)[y*width_+x] == 0) { floatdata.get()[y*width_+x] = 0; } else { floatdata.get()[y*width_+x] = (float)data.get()[y*width_+x] / (float)flat_data[light_index]->filterData(filter_index)[y*width_+x]; } } } // subtract bias, divide flat field cv::Mat floatdatamat(height_, width_, CV_32F, floatdata.get()); // Normalize data to a white reference std::vector<float> values; for (auto y = wtpt_rect_.y(); y < wtpt_rect_.y() + wtpt_rect_.size().height(); ++y) { for (auto x = wtpt_rect_.x(); x < wtpt_rect_.x() + wtpt_rect_.size().width(); ++x) { values.push_back(floatdata.get()[y*width_+x]); } } std::nth_element(values.begin(), values.begin()+(values.size()/2), values.end()); // median sort in constant time float measured_wtpt = values[values.size()/2]; for (auto y = 0; y < height_; ++y) { for (auto x = 0; x < width_; ++x) { floatdata.get()[y*width_+x] /= (measured_wtpt / absolute_wtpt_values_[filter_index]); } } if (filter_index == 0) { // use first filter as registration target for (auto y = 0; y < height_; ++y) { for (auto x = 0; x < width_; ++x) { regdata.get()[y*width_+x] = floatdata.get()[y*width_+x]; } } cv::Mat regdatamat(height_, width_, CV_32F, regdata.get()); } else { // Register image to regtarget_data // Phase-correlate based registration algorithm to align image planes based on two concentric circle targets // Concentric targets are used because of their non-repeating nature; phase correlate gets tripped up by repeating patterns as the peaks can be matched at errant points //cv::mat construction is efficient and does not copy data. Initialize registration target from our regdata cv::Mat registerTo(height_, width_, CV_32F, regdata.get()); cv::Mat reg0_source, reg0_target, reg1_source, reg1_target; cv::Mat reg0_sourcef, reg0_targetf, reg1_sourcef, reg1_targetf; // These cv::Mats' are our registration targets; selected by the user in the main application. //reg0_source = registration target 0 on the image that is going to be registered //reg0_target = registration target 1 on the image that is going to be registered to reg0_sourcef = floatdatamat(cv::Range(regtargets[0].y(), regtargets[0].y() + regtargets[0].size().height()), cv::Range(regtargets[0].x(), regtargets[0].x() + regtargets[0].size().width())); reg0_targetf = registerTo(cv::Range(regtargets[0].y(), regtargets[0].y() + regtargets[0].size().height()), cv::Range(regtargets[0].x(), regtargets[0].x() + regtargets[0].size().width()));// - (reg_size/2), regtargets[0].y + (reg_size/2)), cv::Range(regtargets[0].x - (reg_size/2), regtargets[0].x + (reg_size/2))); reg1_sourcef = floatdatamat(cv::Range(regtargets[1].y(), regtargets[1].y() + regtargets[1].size().height()), cv::Range(regtargets[1].x(), regtargets[1].x() + regtargets[1].size().width()));// - (reg_size/2), regtargets[1].y + (reg_size/2)), cv::Range(regtargets[1].x - (reg_size/2), regtargets[1].x + (reg_size/2))); reg1_targetf = registerTo(cv::Range(regtargets[1].y(), regtargets[1].y() + regtargets[1].size().height()), cv::Range(regtargets[1].x(), regtargets[1].x() + regtargets[1].size().width()));// - (reg_size/2), regtargets[1].y + (reg_size/2)), cv::Range(regtargets[1].x - (reg_size/2), regtargets[1].x + (reg_size/2))); double min, max; cv::Point minLoc, maxLoc; cv::minMaxLoc(reg0_sourcef, &min, &max, &minLoc, &maxLoc); reg0_sourcef *= 255/max; cv::minMaxLoc(reg1_sourcef, &min, &max, &minLoc, &maxLoc); reg1_sourcef *= 255/max; cv::minMaxLoc(reg0_targetf, &min, &max, &minLoc, &maxLoc); reg0_targetf *= 255/max; cv::minMaxLoc(reg1_targetf, &min, &max, &minLoc, &maxLoc); reg1_targetf *= 255/max; reg0_sourcef.convertTo(reg0_source, CV_8U); reg0_targetf.convertTo(reg0_target, CV_8U); reg1_sourcef.convertTo(reg1_source, CV_8U); reg1_targetf.convertTo(reg1_target, CV_8U); cv::adaptiveThreshold(reg0_source, reg0_source, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2); cv::adaptiveThreshold(reg0_target, reg0_target, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2); cv::adaptiveThreshold(reg1_source, reg1_source, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2); cv::adaptiveThreshold(reg1_target, reg1_target, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2); reg0_source.convertTo(reg0_source, CV_32F); reg1_source.convertTo(reg1_source, CV_32F); reg0_target.convertTo(reg0_target, CV_32F); reg1_target.convertTo(reg1_target, CV_32F); reg0_sourcef /= 255; reg0_targetf /= 255; reg1_sourcef /= 255; reg1_targetf /= 255; cv::Point2d offset_center = cv::phaseCorrelate(reg0_source, reg0_target); cv::Point2d offset_corner = cv::phaseCorrelate(reg1_source, reg1_target); float r, r_prime, deltaX, deltaY; deltaX = offset_corner.x - offset_center.x; deltaY = offset_corner.y - offset_center.y; r = pow((regtargets[1].center().x() - regtargets[0].center().x()), 2) + pow((regtargets[1].center().y() - regtargets[0].center().y()), 2); r = sqrt(r); r_prime = pow((regtargets[1].center().x() - regtargets[0].center().x() + deltaX), 2) + pow((regtargets[1].center().y() - regtargets[0].center().y() + deltaY), 2); r_prime = sqrt(r_prime); float scale = r_prime / r; float trans_x = (floatdatamat.size().width / 2) * (1-scale); float trans_y = (floatdatamat.size().height / 2) * (1-scale); std::vector<float> matrix_data(6); matrix_data[0] = scale; matrix_data[1] = 0; matrix_data[2] = trans_x; matrix_data[3] = 0; matrix_data[4] = scale; matrix_data[5] = trans_y; cv::Mat affine(2, 3, CV_32F, matrix_data.data()); cv::Mat scaled; cv::warpAffine(floatdatamat, scaled, affine, floatdatamat.size()); cv::Mat scaled_target = scaled(cv::Range(regtargets[0].y(), regtargets[0].y() + regtargets[0].size().height()), cv::Range(regtargets[0].x(), regtargets[0].x() + regtargets[0].size().width())); cv::Point2d translation_offset = cv::phaseCorrelate(scaled_target, reg0_target); matrix_data[2] += translation_offset.x; matrix_data[5] += translation_offset.y; cv::warpAffine(floatdatamat, floatdatamat, affine, floatdatamat.size()); } if (raw_tiff_path.size() > 0) { TIFFSetField(rawdata_tiff, TIFFTAG_IMAGEWIDTH, width_); TIFFSetField(rawdata_tiff, TIFFTAG_IMAGELENGTH, height_); TIFFSetField(rawdata_tiff, TIFFTAG_BITSPERSAMPLE, sizeof(float) * 8); TIFFSetField(rawdata_tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); TIFFSetField(rawdata_tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(rawdata_tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(rawdata_tiff, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField(rawdata_tiff, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); TIFFSetField(rawdata_tiff, TIFFTAG_WTPTVAL, absolute_wtpt_values_[filter_index]); TIFFSetField(rawdata_tiff, TIFFTAG_WTPTMEASURED, measured_wtpt); TIFFSetField(rawdata_tiff, TIFFTAG_PAGENUMBER, page_index); for (auto row = 0; row < height_; ++row) { TIFFWriteScanline(rawdata_tiff, &floatdata.get()[row*width_], row); } TIFFWriteDirectory(rawdata_tiff); ++page_index; } int wavelength = filter_->wavelengthAtPos(filter_index); std::vector<float> cmf = filter_->cmfValues(wavelength); float illuminant = filter_->illuminantValue(wavelength); for (auto y = 0; y < height_; ++y) { for (auto x = 0; x < width_; ++x) { for (auto xyz_index = 0; xyz_index < 3; ++xyz_index) { xyz_data[light_index].get()->filterData(xyz_index)[y*width_+x] += floatdata.get()[y*width_+x] * cmf[xyz_index] * illuminant; } } } } } if (raw_tiff_path.size() > 0) { TIFFClose(rawdata_tiff); } // Scale xyz data by scalar constant for (auto light = 0; light < nlights_; ++light) { for (auto y = 0; y < height_; ++y) { for (auto x = 0; x < width_; ++x) { for (auto xyz_index = 0; xyz_index < 3; ++xyz_index) { xyz_data[light].get()->filterData(xyz_index)[y*width_+x] /= scalar_constant[xyz_index]; } } } } std::vector<XYZImage*> xyz_ptr; for (auto i = 0; i < xyz_data.size(); ++i) { xyz_ptr.push_back(xyz_data[i].get()); } std::vector<float> weights(nlights_); for (auto weight = 0; weight < weights.size(); ++weight) { weights[weight] = 1.0 / float(nlights_); } master_xyz = std::shared_ptr<XYZImage>(new XYZImage(xyz_ptr, nlights_, weights)); }