void save(Archive & ar, const ::cv::Mat& m, const unsigned int version) { size_t elem_size = m.elemSize(); size_t elem_type = m.type(); ar & m.cols; ar & m.rows; ar & elem_size; ar & elem_type; const size_t data_size = m.cols * m.rows * elem_size; ar & boost::serialization::make_array(m.ptr(), data_size); }
void glTexToCVmat(cv::Mat& image, int width, int height) { // http://stackoverflow.com/questions/9097756/converting-data-from-glreadpixels-to-opencvmat/ image.create(height, width, CV_8UC3); // Use fast 4-byte alignment (default anyway) if possible glPixelStorei(GL_PACK_ALIGNMENT, (image.step & 3) ? 1 : 4); // Set length of one complete row in destination data (doesn't need to equal image.cols) glPixelStorei(GL_PACK_ROW_LENGTH, image.step/image.elemSize()); // Read pixels into Mat. OpenCV stores colors as BGR rather than RGB glReadPixels(0, 0, image.cols, image.rows, GL_BGR, GL_UNSIGNED_BYTE, image.data); }
void cv::ocl::oclMat::download(cv::Mat &m) const { CV_DbgAssert(!this->empty()); // int t = type(); // if(download_channels == 3) //{ // t = CV_MAKETYPE(depth(), 3); //} m.create(wholerows, wholecols, type()); if(m.channels() == 3) { int pitch = wholecols * 3 * m.elemSize1(); int tail_padding = m.elemSize1() * 3072; int err; cl_mem temp = clCreateBuffer((cl_context)clCxt->oclContext(), CL_MEM_READ_WRITE, (pitch * wholerows + tail_padding - 1) / tail_padding * tail_padding, 0, &err); openCLVerifyCall(err); convert_C4C3(*this, temp); openCLMemcpy2D(clCxt, m.data, m.step, temp, pitch, wholecols * m.elemSize(), wholerows, clMemcpyDeviceToHost, 3); //int* cputemp=new int[wholecols*wholerows * 3]; //int* cpudata=new int[this->step*this->wholerows/sizeof(int)]; //openCLSafeCall(clEnqueueReadBuffer(clCxt->impl->clCmdQueue, temp, CL_TRUE, // 0, wholecols*wholerows * 3* sizeof(int), cputemp, 0, NULL, NULL)); //openCLSafeCall(clEnqueueReadBuffer(clCxt->impl->clCmdQueue, (cl_mem)data, CL_TRUE, // 0, this->step*this->wholerows, cpudata, 0, NULL, NULL)); //for(int i=0;i<wholerows;i++) //{ // int *a = cputemp+i*wholecols * 3,*b = cpudata + i*this->step/sizeof(int); // for(int j=0;j<wholecols;j++) // { // if((a[3*j] != b[4*j])||(a[3*j+1] != b[4*j+1])||(a[3*j+2] != b[4*j+2])) // printf("rows=%d,cols=%d,cputtemp=%d,%d,%d;cpudata=%d,%d,%d\n", // i,j,a[3*j],a[3*j+1],a[3*j+2],b[4*j],b[4*j+1],b[4*j+2]); // } //} //delete []cputemp; //delete []cpudata; openCLSafeCall(clReleaseMemObject(temp)); } else { openCLMemcpy2D(clCxt, m.data, m.step, data, step, wholecols * elemSize(), wholerows, clMemcpyDeviceToHost); } Size wholesize; Point ofs; locateROI(wholesize, ofs); m.adjustROI(-ofs.y, ofs.y + rows - wholerows, -ofs.x, ofs.x + cols - wholecols); }
void ReadMatBin(std::ifstream& stream, cv::Mat &output_mat) { // Read in the number of rows, columns and the data type int row, col, type; stream.read((char*)&row, 4); stream.read((char*)&col, 4); stream.read((char*)&type, 4); output_mat = cv::Mat(row, col, type); int size = output_mat.rows * output_mat.cols * output_mat.elemSize(); stream.read((char *)output_mat.data, size); }
bool detectandshow( Alpr* alpr, cv::Mat frame, std::string region, bool writeJson) { timespec startTime; getTimeMonotonic(&startTime); std::vector<AlprRegionOfInterest> regionsOfInterest; regionsOfInterest.push_back(AlprRegionOfInterest(0,0, frame.cols, frame.rows)); AlprResults results = alpr->recognize(frame.data, frame.elemSize(), frame.cols, frame.rows, regionsOfInterest ); timespec endTime; getTimeMonotonic(&endTime); double totalProcessingTime = diffclock(startTime, endTime); if (measureProcessingTime) std::cout << "Total Time to process image: " << totalProcessingTime << "ms." << std::endl; if (writeJson) { std::cout << alpr->toJson( results ) << std::endl; } else { for (int i = 0; i < results.plates.size(); i++) { std::cout << "plate" << i << ": " << results.plates[i].topNPlates.size() << " results"; if (measureProcessingTime) std::cout << " -- Processing Time = " << results.plates[i].processing_time_ms << "ms."; std::cout << std::endl; if (results.plates[i].regionConfidence > 0) std::cout << "State ID: " << results.plates[i].region << " (" << results.plates[i].regionConfidence << "% confidence)" << std::endl; for (int k = 0; k < results.plates[i].topNPlates.size(); k++) { std::cout << " - " << results.plates[i].topNPlates[k].characters << "\t confidence: " << results.plates[i].topNPlates[k].overall_confidence; if (templatePattern.size() > 0) std::cout << "\t pattern_match: " << results.plates[i].topNPlates[k].matches_template; std::cout << std::endl; } } } return results.plates.size() > 0; }
//! Read cv::Mat from binary void readMatBinary(std::ifstream& ifs, cv::Mat& in_mat) { if(!ifs.is_open()){ throw new orArgException("Not opened"); } int rows, cols, type; ifs.read((char*)(&rows), sizeof(int)); ifs.read((char*)(&cols), sizeof(int)); ifs.read((char*)(&type), sizeof(int)); in_mat.release(); in_mat.create(rows, cols, type); ifs.read((char*)(in_mat.data), in_mat.elemSize() * in_mat.total()); }
// Function turn a cv::Mat into a texture void matToTexture(GLuint textureID, cv::Mat& mat) { // Bind to our texture handle glBindTexture(GL_TEXTURE_2D, textureID); // Set texture interpolation methods for minification and magnification glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S , GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //use fast 4-byte alignment (default anyway) if possible glPixelStorei(GL_PACK_ALIGNMENT, (mat.step & 3) ? 1 : 4); //set length of one complete row in destination data (doesn't need to equal img.cols) glPixelStorei(GL_PACK_ROW_LENGTH, mat.step/mat.elemSize()); // Set incoming texture format GLenum inputColourFormat = GL_BGR; GLenum inputType = GL_UNSIGNED_BYTE; GLenum internalFormat = GL_RGBA; if (mat.channels() == 1) { if (mat.depth() == CV_8U) { inputColourFormat = GL_RED_INTEGER; inputType = GL_UNSIGNED_BYTE; internalFormat = GL_RGBA8UI; } else { inputColourFormat = GL_RED_INTEGER; inputType = GL_UNSIGNED_SHORT; internalFormat = GL_RGBA16UI; } } // Create the texture glTexImage2D(GL_TEXTURE_2D, // Type of texture 0, // Pyramid level (for mip-mapping) - 0 is the top level internalFormat, // Internal colour format to convert to mat.cols, // Image width i.e. 640 for Kinect in standard mode mat.rows, // Image height i.e. 480 for Kinect in standard mode 0, // Border width in pixels (can either be 1 or 0) inputColourFormat, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.) inputType, // Image data type mat.data); // The actual image data itself glBindTexture(GL_TEXTURE_2D, 0); }
void hulo::readMatBin(std::string filename, cv::Mat& mat) { std::ifstream ifs(filename, std::ios::binary); CV_Assert(ifs.is_open()); int rows, cols, type; ifs.read((char*) (&rows), sizeof(int)); if (rows == 0) { return; } ifs.read((char*) (&cols), sizeof(int)); ifs.read((char*) (&type), sizeof(int)); mat.release(); mat.create(rows, cols, type); ifs.read((char*) (mat.data), mat.elemSize() * mat.total()); }
void hulo::saveMatBin(std::string filename, cv::Mat& mat) { std::ofstream ofs(filename, std::ios::binary); CV_Assert(ofs.is_open()); if (mat.empty()) { int s = 0; ofs.write((const char*) (&s), sizeof(int)); return; } int type = mat.type(); ofs.write((const char*) (&mat.rows), sizeof(int)); ofs.write((const char*) (&mat.cols), sizeof(int)); ofs.write((const char*) (&type), sizeof(int)); ofs.write((const char*) (mat.data), mat.elemSize() * mat.total()); }
void DiffImage::applyIntensityCorrection(cv::Mat &image) { if (image.total() != intensityCorrectionImage_.total()) return; #pragma omp parallel for private(x, y, c) for (int x = 0; x < image.cols; ++x) { for (int y = 0; y < image.rows; ++y) { for (int c = 0; c < image.channels(); ++c) { const int index = y * image.step + x * image.elemSize() + c; auto val = image.data[index] * (1.0 * intensityCorrectionImage_.data[index] / 100); if (val > 255) val = 255; image.data[index] = static_cast<int>(pow(val / 255.0, gamma_) * 255); } } } }
void SensorData::setUserDataRaw(const cv::Mat & userDataRaw) { if(!userDataRaw.empty() && (!_userDataCompressed.empty() || !_userDataRaw.empty())) { UWARN("Cannot write new user data (%d bytes) over existing user " "data (%d bytes, %d compressed). Set user data of %d to null " "before setting a new one.", int(userDataRaw.total()*userDataRaw.elemSize()), int(_userDataRaw.total()*_userDataRaw.elemSize()), _userDataCompressed.cols, this->id()); return; } _userDataRaw = userDataRaw; _userDataCompressed = cv::Mat(); }
ptrobot2D_test_world_impl(const std::string& aFileName, double aRobotRadius = 1.0) { #ifdef REAK_HAS_OPENCV world_map_image = cv::imread(aFileName); if(world_map_image.empty()) throw std::ios_base::failure("Could not open the world map image '" + aFileName + "'! File is missing, empty or invalid!"); world_map_output = world_map_image.clone(); grid_width = world_map_image.size().width; grid_height = world_map_image.size().height; bpp = world_map_image.elemSize(); for(int y = 0; y < grid_height; ++y) { uchar* color_bits = world_map_image.ptr(y); for(int x = 0; x < grid_width; ++x) { if( (color_bits[2] == 0) && (color_bits[0] == 255) && (color_bits[1] == 0) ) { //this is the start position. start_pos[0] = x; start_pos[1] = y; } else if( (color_bits[2] == 0) && (color_bits[0] == 0) && (color_bits[1] == 255) ) { //this is the goal position. goal_pos[0] = x; goal_pos[1] = y; }; color_bits += bpp; }; }; // int iRobotRadius = int(std::fabs(aRobotRadius)); // if(iRobotRadius > 0) { // cv::GaussianBlur(world_map_output,world_map_image, // cv::Size(iRobotRadius * 2 + 1, iRobotRadius * 2 + 1), // aRobotRadius // ); // }; #else grid_width = 500; grid_height = 500; start_pos = ptrobot2D_test_world::point_type(1.0,1.0); goal_pos = ptrobot2D_test_world::point_type(498.0,498.0); #endif };
void CFast::convertKeypoints(const cv::Mat& cvmKeyPoints_, std::vector<cv::KeyPoint>* pvKeyPoints_) { if (cvmKeyPoints_.empty()) return; CV_Assert(cvmKeyPoints_.rows == ROWS_COUNT && cvmKeyPoints_.elemSize() == 4); int nPoints = cvmKeyPoints_.cols; pvKeyPoints_->resize(nPoints); const short2* ps2LocationRow = cvmKeyPoints_.ptr<short2>(LOCATION_ROW); const float* pfResponseRow = cvmKeyPoints_.ptr<float>(RESPONSE_ROW); for (int i = 0; i < nPoints; ++i){ cv::KeyPoint kp(ps2LocationRow[i].x, ps2LocationRow[i].y, static_cast<float>(FEATURE_SIZE), -1, pfResponseRow[i]); (*pvKeyPoints_)[i] = kp; } return; }
/*! \param[out] ofs output file stream \param[in] out_mat mat to save */ bool writeMatBinary(std::ofstream& ofs, const cv::Mat& out_mat) { if(!ofs.is_open()){ return false; } if(out_mat.empty()){ int s = 0; ofs.write((const char*)(&s), sizeof(int)); return true; } int type = out_mat.type(); ofs.write((const char*)(&out_mat.rows), sizeof(int)); ofs.write((const char*)(&out_mat.cols), sizeof(int)); ofs.write((const char*)(&type), sizeof(int)); ofs.write((const char*)(out_mat.data), out_mat.elemSize() * out_mat.total()); return true; }
// image는 흑백 영상이어야 한다. // 크기는 640/480 이어야 한다. int cStreamingSender::Send(const cv::Mat &image) { if (READY == m_state) { // 이미지를 변조한다. uchar *data = image.data; int buffSize = image.total() * image.elemSize(); // Gray Scale if (m_isConvertGray) { cvtColor(image, m_gray, CV_RGB2GRAY); data = m_gray.data; buffSize = m_gray.total() * m_gray.elemSize(); } // 압축 if (m_isCompressed) { vector<int> p(3); p[0] = CV_IMWRITE_JPEG_QUALITY; p[1] = m_jpgCompressQuality; p[2] = 0; cv::imencode(".jpg", m_isConvertGray ? m_gray : image, m_compBuffer, p); data = (uchar*)&m_compBuffer[0]; buffSize = m_compBuffer.size(); } return SendImage(data, buffSize, m_isConvertGray, m_isCompressed); } else if (SPLIT == m_state) { if (SendSplit()) { m_state = READY; ++m_chunkId; if (m_chunkId > 100) m_chunkId = 0; } } return 0; }
// Save cv::Mat as binary bool BinaryMat::SaveMatBinary(const std::string& filename, const cv::Mat& out_mat) { std::ofstream ofs(filename, std::ios::binary); if (!ofs.is_open()) { return false; } if (out_mat.empty()) { int s = 0; ofs.write((const char*)(&s), sizeof(int)); return true; } int type = out_mat.type(); ofs.write((const char*)(&out_mat.rows), sizeof(int)); ofs.write((const char*)(&out_mat.cols), sizeof(int)); ofs.write((const char*)(&type), sizeof(int)); ofs.write((const char*)(out_mat.data), out_mat.elemSize() * out_mat.total()); return true; }
virtual bool write( const char * table, const char * name, const cv::Mat & mat ) { int t = mat.type(); int w = mat.cols; int h = mat.rows; string q = format("insert into %s values(?, ?, ?, ?, ?);", table); MYSQL_STMT * stmt = mysql_stmt_init(mysql); if ( ! stmt ) return _error("write init statement"); if ( mysql_stmt_prepare(stmt,q.c_str(),q.length()) ) return _error("write prepare statement"); MYSQL_BIND bind[5] = {0}; bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= (void*)name; bind[0].buffer_length= strlen(name); bind[1].buffer_type= MYSQL_TYPE_LONG; bind[1].buffer= (char *)(&t); bind[2].buffer_type= MYSQL_TYPE_LONG; bind[2].buffer= (char *)(&w); bind[3].buffer_type= MYSQL_TYPE_LONG; bind[3].buffer= (char *)(&h); bind[4].buffer_type= MYSQL_TYPE_MEDIUM_BLOB; bind[4].buffer= (char *)(mat.data); bind[4].buffer_length= mat.total()*mat.elemSize(); if ( mysql_stmt_bind_param(stmt,bind) ) return _error(stmt,"write bind params"); if ( mysql_stmt_execute(stmt) ) return _error(stmt,"write execute"); mysql_stmt_close(stmt); return true; }
double multiplyImage(cv::Mat &image, cv::Mat gain) { cv::Mat stub, b, g, r, stubGain; std::vector<cv::Mat> arrayColor; arrayColor.push_back(b); arrayColor.push_back(g); arrayColor.push_back(r); cv::split(image, arrayColor); int64 begin, end; begin = cv::getTickCount(); switch (gain.elemSize()) { case 1: gain.convertTo(stubGain, CV_32FC1, 1/255.0f); for (unsigned int i = 0; i < arrayColor.size(); i++) { arrayColor[i].convertTo(stub, CV_32FC1); multiply(stub, stubGain, arrayColor[i], 1.0, CV_8UC1); } break; case 2: for (unsigned int i = 0; i < arrayColor.size(); i++) { multiply(arrayColor[i].data, (short*)gain.data, arrayColor[i].data, arrayColor[i].rows*arrayColor[i].cols); } break; case 4: default: for (unsigned int i = 0; i < arrayColor.size(); i++) { arrayColor[i].convertTo(stub, CV_32FC1); multiply(stub, gain, arrayColor[i], 1.0, CV_8UC1); } break; } end = cv::getTickCount(); cv::merge(arrayColor, image); double tickCountElapsed = double(end - begin); return tickCountElapsed/(double)cv::getTickFrequency(); }
/*! \param[in] ifs input file stream \param[out] in_mat mat to load */ bool readMatBinary(std::ifstream& ifs, cv::Mat& in_mat) { if(!ifs.is_open()){ return false; } int rows, cols, type; ifs.read((char*)(&rows), sizeof(int)); if(rows==0){ return true; } ifs.read((char*)(&cols), sizeof(int)); ifs.read((char*)(&type), sizeof(int)); in_mat.release(); in_mat.create(rows, cols, type); ifs.read((char*)(in_mat.data), in_mat.elemSize() * in_mat.total()); return true; }
void copyMatToImageMSg(const cv::Mat& in, mobots_msgs::ImageWithPoseAndID& out2){ sensor_msgs::Image* out = &out2.image; out->height = in.rows; out->width = in.cols; out->encoding = "bgr8"; out->is_bigendian = 0; out->step = in.cols * in.elemSize(); out->data.resize(in.rows * out->step); if(in.isContinuous()){ memcpy(&out->data[0], in.data, in.rows * out->step); }else{ // Copy row by row uchar* ros_data_ptr = (uchar*)(&out->data[0]); uchar* cv_data_ptr = in.data; for (int i = 0; i < in.rows; i++){ memcpy(ros_data_ptr, cv_data_ptr, out->step); ros_data_ptr += out->step; cv_data_ptr += in.step; } } }
double multiplyImageCuda(cv::Mat &image, cv::Mat gain) { unsigned int image_width = image.cols; unsigned int image_height = image.rows; unsigned int imageSizeGray = image_width * image_height; unsigned int imageSizeColor = imageSizeGray * 3; cudaMemcpy(imageCuda, image.data, imageSizeColor*sizeof(char), cudaMemcpyHostToDevice); // calculate grid size dim3 block(16, 16, 1); dim3 grid(image_width / block.x, image_height / block.y, 1); int64 begin, end; switch (gain.elemSize()) { case 1: begin = cv::getTickCount(); cudaMemcpy(gainByteCuda, gain.data, imageSizeGray*sizeof(char), cudaMemcpyHostToDevice); end = cv::getTickCount(); launchCudaProcessByte(grid, block, 0, gainByteCuda, imageCuda, imageResult, image_width); break; case 2: begin = cv::getTickCount(); cudaMemcpy(gainCuda, gain.data, imageSizeGray*sizeof(short), cudaMemcpyHostToDevice); end = cv::getTickCount(); launchCudaProcessHalf(grid, block, 0, gainCuda, imageCuda, imageResult, image_width); break; case 4: begin = cv::getTickCount(); cudaMemcpy(gainFloatCuda, gain.data, imageSizeGray*sizeof(float), cudaMemcpyHostToDevice); end = cv::getTickCount(); launchCudaProcessFloat(grid, block, 0, gainFloatCuda, imageCuda, imageResult, image_width); break; } cudaMemcpy(image.data, imageResult, imageSizeColor*sizeof(char), cudaMemcpyDeviceToHost); double tickCountElapsed = double(end - begin); return tickCountElapsed/(double)cv::getTickFrequency(); }
QImage Listener::cvtCvMat2QImage(const cv::Mat & image) { QImage qtemp; if(!image.empty() && image.depth() == CV_8U) { const unsigned char * data = image.data; qtemp = QImage(image.cols, image.rows, QImage::Format_RGB32); for(int y = 0; y < image.rows; ++y, data += image.cols*image.elemSize()) { for(int x = 0; x < image.cols; ++x) { QRgb * p = ((QRgb*)qtemp.scanLine (y)) + x; *p = qRgb(data[x * image.channels()+2], data[x * image.channels()+1], data[x * image.channels()]); } } } else if(!image.empty() && image.depth() != CV_8U) { printf("Wrong image format, must be 8_bits\n"); } return qtemp; }
static void randu(cv::Mat& m) { const int bigValue = 0x00000FFF; if (m.depth() < CV_32F) { int minmax[] = {0, 256}; cv::Mat mr = cv::Mat(m.rows, (int)(m.cols * m.elemSize()), CV_8U, m.ptr(), m.step[0]); cv::randu(mr, cv::Mat(1, 1, CV_32S, minmax), cv::Mat(1, 1, CV_32S, minmax + 1)); } else if (m.depth() == CV_32F) { //float minmax[] = {-FLT_MAX, FLT_MAX}; float minmax[] = {-bigValue, bigValue}; cv::Mat mr = m.reshape(1); cv::randu(mr, cv::Mat(1, 1, CV_32F, minmax), cv::Mat(1, 1, CV_32F, minmax + 1)); } else { //double minmax[] = {-DBL_MAX, DBL_MAX}; double minmax[] = {-bigValue, bigValue}; cv::Mat mr = m.reshape(1); cv::randu(mr, cv::Mat(1, 1, CV_64F, minmax), cv::Mat(1, 1, CV_64F, minmax + 1)); } }
static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier) { return ippiSuggestThreadsNum(image.cols, image.rows, image.elemSize(), multiplier); }
std::string describe(cv::Mat const &mat) { std::ostringstream out; out << mat.rows << "x" << mat.cols; out << ", " << mat.channels() << " channels"; out << ", type " << CV_MAT_DEPTH(mat.type()) << ", " << mat.elemSize1() << " byte elemsize1, " << mat.elemSize() << " byte elemsize"; return out.str(); }
/** @brief 色相だけのヒストグラムを計算する @param src ヒストグラムを計算する画像 */ void HIST::calcHistgramHue(cv::Mat &src) { if(src.data == NULL) return; // グラフのデータ間の距離 stepH = (double)ui.histgramH->width()/180; cv::cvtColor(src, src, cv::COLOR_BGR2HSV); int count[180]; int max = 0; // 初期化 for (int i = 0; i < 180; i++) count[i] = 0; // 色相の各値の個数を取得 for (int j = 0; j < src.cols; j++) for (int i = 0; i < src.rows; i++) // ほぼ白(彩度≒0)は無視 if(src.data[i * src.step + j * src.elemSize() + 1] > 3) count[src.data[i * src.step + j * src.elemSize()]]++; cv::cvtColor(src, src, cv::COLOR_HSV2BGR); // スケーリング定数(一番多い個数)の取得 for (int i = 0; i < 180; i++) if(max < count[i]) max = count[i]; // スケーリング double histgram[180]; for (int i = 0; i < 180; i++) histgram[i] = (double)count[i] / max * 200; /** 簡易グラフ作成 **/ int gWidth = 180 * stepH; int gHeight = 200; // 格子画像 cv::Mat baseGraph(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)); // 色相のヒストグラム画像 cv::Mat hueGraph(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)); // 上記2つを乗算ブレンディングした最終的に描画する画像 cv::Mat graph(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)); cv::cvtColor(hueGraph, hueGraph, cv::COLOR_BGR2HSV); for (int j = 0; j < hueGraph.rows; j++){ for (int i = 0; i < hueGraph.cols; i++){ hueGraph.data[j * hueGraph.step + i * hueGraph.elemSize() + 0] = (int)((double)i/stepH); hueGraph.data[j * hueGraph.step + i * hueGraph.elemSize() + 1] = 220; hueGraph.data[j * hueGraph.step + i * hueGraph.elemSize() + 2] = 180; } } cv::cvtColor(hueGraph, hueGraph, cv::COLOR_HSV2BGR); // 横のメモリ for (int i = 0; i < 20; i++) if(!(i%4)) cv::line(baseGraph, cv::Point(0, i*10), cv::Point(gWidth, i*10), cv::Scalar(180, 180, 180), 2); else cv::line(baseGraph, cv::Point(0, i*10), cv::Point(gWidth, i*10), cv::Scalar(200, 200, 200), 1); // 色相のグラフ for (int i = 0; i < 180; i++) cv::line(hueGraph, cv::Point((int)(i*stepH), 0), cv::Point((int)(i*stepH), (int)histgram[i]), cv::Scalar(180, 180, 180), 2); // 折れ線 for (int i = 0; i < 180; i++) cv::line(hueGraph, cv::Point((int)(i*stepH), (int)histgram[i]), cv::Point((int)((i+1)*stepH), (int)histgram[i+1]), cv::Scalar(90, 90, 90), 2, CV_AA); // 合成 blend(baseGraph, hueGraph, graph, blendType::MULTI); // 上下を反転 cv::flip(graph, graph, 0); drawForQtLabel(graph, ui.histgramH, false); }
unsigned long ipa_Utils::FilterSpeckles(cv::Mat& img, int maxSpeckleSize, double maxDiff, cv::Mat& _buf ) { CV_Assert( img.type() == CV_32FC3 ); float newVal = 0; int width = img.cols, height = img.rows, npixels = width*height; size_t bufSize = npixels*(int)(sizeof(cv::Point_<short>) + sizeof(int) + sizeof(uchar)); if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize ) _buf.create(1, bufSize, CV_8U); uchar* buf = _buf.data; int i, j, dstep = img.step/sizeof(cv::Vec3f); int* labels = (int*)buf; buf += npixels*sizeof(labels[0]); cv::Point_<short>* wbuf = (cv::Point_<short>*)buf; buf += npixels*sizeof(wbuf[0]); uchar* rtype = (uchar*)buf; int curlabel = 0; // clear out label assignments memset(labels, 0, npixels*sizeof(labels[0])); for( i = 0; i < height; i++ ) { cv::Vec3f* ds = img.ptr<cv::Vec3f>(i); int* ls = labels + width*i; for( j = 0; j < width; j++ ) { if( ds[j][2] != newVal ) // not a bad disparity { if( ls[j] ) // has a label, check for bad label { if( rtype[ls[j]] ) // small region, zero out disparity { ds[j][0] = (float)newVal; ds[j][1] = (float)newVal; ds[j][2] = (float)newVal; } } // no label, assign and propagate else { cv::Point_<short>* ws = wbuf; // initialize wavefront cv::Point_<short> p((short)j, (short)i); // current pixel curlabel++; // next label int count = 0; // current region size ls[j] = curlabel; // wavefront propagation while( ws >= wbuf ) // wavefront not empty { count++; // put neighbors onto wavefront cv::Vec3f* dpp = &img.at<cv::Vec3f>(p.y, p.x); cv::Vec3f dp = *dpp; int* lpp = labels + width*p.y + p.x; if( p.x < width-1 && !lpp[+1] && dpp[+1][2] != newVal && std::abs(dp[2] - dpp[+1][2]) <= maxDiff ) { lpp[+1] = curlabel; *ws++ = cv::Point_<short>(p.x+1, p.y); } if( p.x > 0 && !lpp[-1] && dpp[-1][2] != newVal && std::abs(dp[2] - dpp[-1][2]) <= maxDiff ) { lpp[-1] = curlabel; *ws++ = cv::Point_<short>(p.x-1, p.y); } if( p.y < height-1 && !lpp[+width] && dpp[+dstep][2] != newVal && std::abs(dp[2] - dpp[+dstep][2]) <= maxDiff ) { lpp[+width] = curlabel; *ws++ = cv::Point_<short>(p.x, p.y+1); } if( p.y > 0 && !lpp[-width] && dpp[-dstep][2] != newVal && std::abs(dp[2] - dpp[-dstep][2]) <= maxDiff ) { lpp[-width] = curlabel; *ws++ = cv::Point_<short>(p.x, p.y-1); } // pop most recent and propagate // NB: could try least recent, maybe better convergence p = *--ws; } // assign label type if( count <= maxSpeckleSize ) // speckle region { rtype[ls[j]] = 1; // small region label ds[j][0] = (float)newVal; ds[j][1] = (float)newVal; ds[j][2] = (float)newVal; } else rtype[ls[j]] = 0; // large region label } } } } return ipa_Utils::RET_OK; }
/** @brief RGBのヒストグラムを計算する @param src ヒストグラムを計算する画像 */ void HIST::calcHistgram(cv::Mat &src) { if(src.data == NULL) return; // グラフのデータ間の距離 step = (double)ui.histgramRGB->width()/256; int count[256][3]; int max = 0; // 初期化 for (int i = 0; i < 256; i++) for (int c = 0; c < 3; c++) count[i][c] = 0; // RGBごとに輝度の個数を取得 for (int j = 0; j < src.cols; j++) for (int i = 0; i < src.rows; i++) for (int c = 0; c < 3; c++) count[src.data[i * src.step + j * src.elemSize() + c]][c]++; // 0と255はだいたい極端に多くなるので無視する for (int c = 0; c < 3; c++) count[0][c] = count[255][c] = 0; // スケーリング定数(一番多い輝度の個数)の取得 for (int i = 0; i < 256; i++) for (int c = 0; c < 3; c++) if(max < count[i][c]) max = count[i][c]; // スケーリング double histgram[256][3]; for (int i = 0; i < 256; i++) for (int c = 0; c < 3; c++) histgram[i][c] = (double)count[i][c] / max * 200; /** 簡易グラフ作成 **/ int gWidth = 256 * step; int gHeight = 200; // 格子画像 cv::Mat baseGraph(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)); // RGBごとのヒストグラム画像 cv::Mat rgbGraph[3] = { cv::Mat(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)), cv::Mat(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)), cv::Mat(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)) }; // 上記4つを乗算ブレンディングした最終的に描画する画像 cv::Mat graph(gHeight, gWidth, CV_8UC3, cv::Scalar(255, 255, 255)); // 横のメモリ for (int i = 0; i < 20; i++) if(!(i%4)) cv::line(baseGraph, cv::Point(0, i*10), cv::Point(gWidth, i*10), cv::Scalar(180, 180, 180), 2); else cv::line(baseGraph, cv::Point(0, i*10), cv::Point(gWidth, i*10), cv::Scalar(200, 200, 200), 1); // 縦のメモリ for (int i = 0; i < 5; i++) cv::line(baseGraph, cv::Point(i*50*step, 0), cv::Point(i*50*step, gHeight), cv::Scalar(180, 180, 180), 2); // RGBごとのグラフ for (int i = 0; i < 256; i++){ cv::line(rgbGraph[0], cv::Point(i*step, 0), cv::Point(i*step, (int)histgram[i][0]), cv::Scalar(255, 200, 200), 2); cv::line(rgbGraph[1], cv::Point(i*step, 0), cv::Point(i*step, (int)histgram[i][1]), cv::Scalar(200, 255, 200), 2); cv::line(rgbGraph[2], cv::Point(i*step, 0), cv::Point(i*step, (int)histgram[i][2]), cv::Scalar(200, 200, 255), 2); } // 折れ線 for (int i = 0; i < 255; i++){ cv::line(rgbGraph[0], cv::Point(i*step, (int)histgram[i][0]), cv::Point((i+1)*step, (int)histgram[i+1][0]), cv::Scalar(255, 30, 30), 2, CV_AA); cv::line(rgbGraph[1], cv::Point(i*step, (int)histgram[i][1]), cv::Point((i+1)*step, (int)histgram[i+1][1]), cv::Scalar(30, 255, 30), 2, CV_AA); cv::line(rgbGraph[2], cv::Point(i*step, (int)histgram[i][2]), cv::Point((i+1)*step, (int)histgram[i+1][2]), cv::Scalar(30, 30, 255), 2, CV_AA); } // 合成 cv::Mat tmp; blend(rgbGraph[0], rgbGraph[1], tmp, blendType::MULTI); blend(tmp, rgbGraph[2], tmp, blendType::MULTI); blend(baseGraph, tmp, graph, blendType::MULTI); // 上下を反転 cv::flip(graph, graph, 0); drawForQtLabel(graph, ui.histgramRGB, false); }