コード例 #1
0
ファイル: vpImgproc.cpp プロジェクト: npedemon/visp_contrib
/*!
  \ingroup group_imgproc_histogram

  Adjust the contrast of a color image by performing an histogram equalization.
  The intensity distribution is redistributed over the full [0 - 255] range such as the cumulative histogram
  distribution becomes linear. The alpha channel is ignored / copied from the source alpha channel.

  \param I : The color image to apply histogram equalization.
  \param useHSV : If true, the histogram equalization is performed on the value channel (in HSV space), otherwise
  the histogram equalization is performed independently on the RGB channels.
*/
void vp::equalizeHistogram(vpImage<vpRGBa> &I, const bool useHSV) {
  if(I.getWidth()*I.getHeight() == 0) {
    return;
  }

  if(!useHSV) {
    //Split the RGBa image into 4 images
    vpImage<unsigned char> pR(I.getHeight(), I.getWidth());
    vpImage<unsigned char> pG(I.getHeight(), I.getWidth());
    vpImage<unsigned char> pB(I.getHeight(), I.getWidth());
    vpImage<unsigned char> pa(I.getHeight(), I.getWidth());

    vpImageConvert::split(I, &pR, &pG, &pB, &pa);

    //Apply histogram equalization for each channel
    vp::equalizeHistogram(pR);
    vp::equalizeHistogram(pG);
    vp::equalizeHistogram(pB);

    //Merge the result in I
    unsigned int size = I.getWidth()*I.getHeight();
    unsigned char *ptrStart = (unsigned char*) I.bitmap;
    unsigned char *ptrEnd = ptrStart + size*4;
    unsigned char *ptrCurrent = ptrStart;

    unsigned int cpt = 0;
    while(ptrCurrent != ptrEnd) {
      *ptrCurrent = pR.bitmap[cpt];
      ++ptrCurrent;

      *ptrCurrent = pG.bitmap[cpt];
      ++ptrCurrent;

      *ptrCurrent = pB.bitmap[cpt];
      ++ptrCurrent;

      *ptrCurrent = pa.bitmap[cpt];
      ++ptrCurrent;

      cpt++;
    }
  } else {
    vpImage<unsigned char> hue(I.getHeight(), I.getWidth());
    vpImage<unsigned char> saturation(I.getHeight(), I.getWidth());
    vpImage<unsigned char> value(I.getHeight(), I.getWidth());

    unsigned int size = I.getWidth()*I.getHeight();
    //Convert from RGBa to HSV
    vpImageConvert::RGBaToHSV((unsigned char *) I.bitmap, (unsigned char *) hue.bitmap,
        (unsigned char *) saturation.bitmap, (unsigned char *) value.bitmap, size);

    //Histogram equalization on the value plane
    vp::equalizeHistogram(value);

    //Convert from HSV to RGBa
    vpImageConvert::HSVToRGBa((unsigned char*) hue.bitmap, (unsigned char*) saturation.bitmap,
        (unsigned char*) value.bitmap, (unsigned char*) I.bitmap, size);
  }
}
コード例 #2
0
ファイル: cldense-axpy.cpp プロジェクト: 10imaging/clSPARSE
clsparseStatus
cldenseDaxpy(cldenseVector *r,
             const clsparseScalar *alpha, const cldenseVector *x,
             const cldenseVector *y,
             const clsparseControl control)
{
    if (!clsparseInitialized)
    {
        return clsparseNotInitialized;
    }

    //check opencl elements
    if (control == nullptr)
    {
        return clsparseInvalidControlObject;
    }

    clsparse::vector<cl_double> pR (control, r->values, r->num_values);
    clsparse::vector<cl_double> pAlpha(control, alpha->value, 1);
    clsparse::vector<cl_double> pX (control, x->values, x->num_values);
    clsparse::vector<cl_double> pY (control, y->values, y->num_values);

    assert(pR.size() == pY.size());
    assert(pR.size() == pX.size());

    cl_ulong size = pR.size();

    if(size == 0) return clsparseSuccess;

    //nothing to do
    if (pAlpha[0] == 0.0)
    {
        auto pRBuff = pR.data()();
        auto pYBuff = pY.data()();

        //if R is different pointer than Y than copy Y to R
        if (pRBuff != pYBuff)
        {
            // deep copy;
            pR = pY;
        }
        return clsparseSuccess;
    }

    return axpy(pR, pAlpha, pX, pY, control);
}
コード例 #3
0
ファイル: vpImgproc.cpp プロジェクト: npedemon/visp_contrib
/*!
  \ingroup group_imgproc_contrast

  Stretch the contrast of a color image.

  \param I : The color image to stretch the contrast.
*/
void vp::stretchContrast(vpImage<vpRGBa> &I) {
  //Find min and max intensity values
  vpRGBa min = 255, max = 0;

  //Split the RGBa image into 4 images
  vpImage<unsigned char> pR(I.getHeight(), I.getWidth());
  vpImage<unsigned char> pG(I.getHeight(), I.getWidth());
  vpImage<unsigned char> pB(I.getHeight(), I.getWidth());
  vpImage<unsigned char> pa(I.getHeight(), I.getWidth());

  vpImageConvert::split(I, &pR, &pG, &pB, &pa);
  //Min max values calculated for each channel
  unsigned char minChannel, maxChannel;
  pR.getMinMaxValue(minChannel, maxChannel);
  min.R = minChannel;
  max.R = maxChannel;

  pG.getMinMaxValue(minChannel, maxChannel);
  min.G = minChannel;
  max.G = maxChannel;

  pB.getMinMaxValue(minChannel, maxChannel);
  min.B = minChannel;
  max.B = maxChannel;

  pa.getMinMaxValue(minChannel, maxChannel);
  min.A = minChannel;
  max.A = maxChannel;


  //Construct the look-up table
  vpRGBa lut[256];
  unsigned char rangeR = max.R - min.R;
  if(rangeR > 0) {
    for(unsigned int x = min.R; x <= max.R; x++) {
      lut[x].R = 255 * (x - min.R) / rangeR;
    }
  } else {
    lut[min.R].R = min.R;
  }

  unsigned char rangeG = max.G - min.G;
  if(rangeG > 0) {
    for(unsigned int x = min.G; x <= max.G; x++) {
      lut[x].G = 255 * (x - min.G) / rangeG;
    }
  } else {
    lut[min.G].G = min.G;
  }

  unsigned char rangeB = max.B - min.B;
  if(rangeB > 0) {
    for(unsigned int x = min.B; x <= max.B; x++) {
      lut[x].B = 255 * (x - min.B) / rangeB;
    }
  } else {
    lut[min.B].B = min.B;
  }

  unsigned char rangeA = max.A - min.A;
  if(rangeA > 0) {
    for(unsigned int x = min.A; x <= max.A; x++) {
      lut[x].A = 255 * (x - min.A) / rangeA;
    }
  } else {
    lut[min.A].A = min.A;
  }

  I.performLut(lut);
}
コード例 #4
0
IplImage* getTone(const char *filename)
{
	//实现论文中提到的正常铅笔画应有的直方图
	double p1, p2, p3, p[256];
	double temp = sqrt(2 * CV_PI * 10);
	for (int i = 0; i < 256; i++) {
		p1 = 1 / 9.0 * exp(-(256 - i) / 9.0);
		p2 = (i >= 105 && i <= 225) / (225 - 105.0);
		p3 = exp(-(i - 80)*(i - 80) / (2.0 * 10 * 10)) / temp;
		p[i] = 0.52 * p1 + 0.37 * p2 + 0.11 * p3;
	}
	smooth(p, 256);
	smooth(p, 256);
	double sum = 0;
	for (int i = 0; i < 256; i++) sum += p[i];
	for (int i = 0; i < 256; i++) p[i] /= sum;
	double G[256];
	G[0] = p[0];
	for (int i = 1; i < 256; i++) G[i] = G[i - 1] + p[i];

	//计算原图的直方图
	IplImage *pToneImage = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);
	Image img(pToneImage);
	int h = pToneImage->height;
	int w = pToneImage->width;

	CvHistogram *pHis = CreateGrayImageHist(&pToneImage);
	double S[256];
	S[0] = cvQueryHistValue_1D(pHis, 0) / (h*w);
	for (int i = 1; i < 256; i++)
		S[i] = S[i - 1] + cvQueryHistValue_1D(pHis, i) / (h*w);

	//进行直方图匹配
	int index[256];
	for (int i = 0; i < 256; i++) {
		int k = 0;
		for (int j = 1; j < 256; j++)
			if (abs(G[k] - S[i]) > abs(G[j] - S[i])) k = j;
		index[i] = k;
	}

	for (int i = 0; i < h; i++)
		for (int j = 0; j < w; j++) img[i][j] = index[img[i][j]];

	//Pencil Texture Rendering
	IplImage *pRender = cvLoadImage("Tonal Texture.png", CV_LOAD_IMAGE_GRAYSCALE);
	Image pR(pRender);
	double **b = new double*[h];
	for (int i = 0; i < h; i++) 
	{
		b[i] = new double[w];
		for (int j = 0; j < w; j++)
		{
			double H = pR[i % pR.getH()][j % pR.getW()] / 256.0;
			double J = img[i][j] / 256.0;
			double bx = (i) ? b[i - 1][j] : 0;
			double by = (j) ? b[i][j - 1] : 0;
			double A = 0.2 * 2 + log(H)*log(H);
			double B = -2*(0.2*(bx + by) + log(H)*log(J));
			b[i][j] = -B / (2*A);
			img[i][j] = pow(H, b[i][j]) * 256;
		}
	}
	return pToneImage;
}
コード例 #5
0
bool SplitEvaluatorMLClass<Sample, TAppContext>::CalculateSpecificLossAndThreshold(DataSet<Sample, LabelMLClass>& dataset, std::vector<std::pair<double, int> > responses, std::pair<double, double>& score_and_threshold)
{
	// In: samples, sorted responses, out:loss-value+threshold

    // 1) Calculate random thresholds and sort them
    double min_response = responses[0].first;
    double max_response = responses[responses.size()-1].first;
    double d = (max_response - min_response);
    vector<double> random_thresholds(m_appcontext->num_node_thresholds, 0.0);
    for (int i = 0; i < random_thresholds.size(); i++)
        random_thresholds[i] = (randDouble() * d) + min_response;
    sort(random_thresholds.begin(), random_thresholds.end());


    // Declare and init some variables
    vector<double> RClassWeights(m_appcontext->num_classes, 0.0);
    vector<double> LClassWeights(m_appcontext->num_classes, 0.0);
    vector<int> RSamples;
    vector<int> LSamples;
    double RTotalWeight = 0.0;
    double LTotalWeight = 0.0;
    double margin = 0.0;
    double RLoss = 0.0, LLoss = 0.0;
    double BestLoss = 1e16, CombinedLoss = 0.0, TotalWeight = 0.0, BestThreshold = 0.0;
    bool found = false;


    // First, put everything in the right node
    RSamples.resize(responses.size());
    for (int r = 0; r < responses.size(); r++)
    {
        int labelIdx = dataset[responses[r].second]->m_label.class_label;
        double sample_w = dataset[responses[r].second]->m_label.class_weight;

        RClassWeights[labelIdx] += sample_w;
        RTotalWeight += sample_w;
        RSamples[r] = responses[r].second;
    }

    // Now, iterate all responses and calculate Gini indices at the cutoff points (thresholds)
    int th_idx = 0;
    bool stop_search = false;
    for (int r = 0; r < responses.size(); r++)
    {
        // if the current sample is smaller than the current threshold put it to the left side
        if (responses[r].first <= random_thresholds[th_idx])
        {
            int labelIdx = dataset[responses[r].second]->m_label.class_label;
            double cur_sample_weight = dataset[responses[r].second]->m_label.class_weight;

            RClassWeights[labelIdx] -= cur_sample_weight;
            if (RClassWeights[labelIdx] < 0.0)
                RClassWeights[labelIdx] = 0.0;
            LClassWeights[labelIdx] += cur_sample_weight;

            RTotalWeight -= cur_sample_weight;
            if (RTotalWeight < 0.0)
                RTotalWeight = 0.0;
            LTotalWeight += cur_sample_weight;

            LSamples.push_back(RSamples[0]);
            RSamples.erase(RSamples.begin());
        }
        else
        {
            // ok, now we found the first sample having higher response than the current threshold

            // Reset the losses
            RLoss = 0.0, LLoss = 0.0;

            // calculate loss for left and right child nodes
            // RIGHT
			vector<double> pR(RClassWeights.size());
			for (int ci = 0; ci < RClassWeights.size(); ci++)
				pR[ci] = RClassWeights[ci] / RTotalWeight;
			for (int ci = 0; ci < RClassWeights.size(); ci++)
				RLoss += RClassWeights[ci] * ComputeLoss(pR, ci, m_appcontext->global_loss_classification);

            // LEFT
            vector<double> pL(LClassWeights.size());
			for (int ci = 0; ci < LClassWeights.size(); ci++)
				pL[ci] = LClassWeights[ci] / LTotalWeight;
			for (int ci = 0; ci < LClassWeights.size(); ci++)
				LLoss += LClassWeights[ci] * ComputeLoss(pL, ci, m_appcontext->global_loss_classification);

            // Total loss
            CombinedLoss = LLoss + RLoss;

            // best-search ...
            if (CombinedLoss < BestLoss && LTotalWeight > 0.0 && RTotalWeight > 0.0)
            {
                BestLoss = CombinedLoss;
                BestThreshold = random_thresholds[th_idx];
                found = true;
            }

            // next, we have to find the next random threshold that is larger than the current response
            // -> there might be several threshold within the gap between the last response and this one.
            while (responses[r].first > random_thresholds[th_idx])
            {
                if (th_idx < (random_thresholds.size()-1))
                {
                    th_idx++;
                    r--;
                }
                else
                {
                    stop_search = true;
                    break; // all thresholds tested
                }
            }
            // now, we can go on with the next response ...
        }
        if (stop_search)
            break;
    }

    score_and_threshold.first = BestLoss;
    score_and_threshold.second = BestThreshold;
    return found;
}