colour hsl_colour::to_rgb(double aAlpha) const { double c = (1.0 - std::abs(2.0 * lightness() - 1.0)) * saturation(); double h2 = hue() / 60.0; double x = c * (1.0 - std::abs(std::fmod(h2, 2.0) - 1.0)); double r, g, b; if (hue() == undefined_hue()) r = g = b = 0.0; else if (h2 >= 0.0 && h2 < 1.0) r = c, g = x, b = 0.0; else if (h2 >= 1.0 && h2 < 2.0) r = x, g = c, b = 0.0; else if (h2 >= 2.0 && h2 < 3.0) r = 0.0, g = c, b = x; else if (h2 >= 3.0 && h2 < 4.0) r = 0.0, g = x, b = c; else if (h2 >= 4.0 && h2 < 5.0) r = x, g = 0.0, b = c; else if (h2 >= 5.0 && h2 < 6.0) r = c, g = 0.0, b = x; else r = g = b = 0.0; double m = lightness() - 0.5f * c; colour result( static_cast<colour::component>(std::floor((r + m) * 255.0)), static_cast<colour::component>(std::floor((g + m) * 255.0)), static_cast<colour::component>(std::floor((b + m) * 255.0)), static_cast<colour::component>(std::floor(aAlpha * 255.0))); return result; }
/** * @brief Is Camshift Tracker updated or not? * @param img * @param obj * @param hist * @return bool, whether Camshift tracker has been updated or not */ bool CTrackingAlgs::CamshiftUpdateTracker( const cv::Mat& img, const cv::Rect& obj, cv::MatND& hist) { cv::Mat hsv, hue, mask, backproject; cv::cvtColor( img, hsv, CV_BGR2HSV ); int _vmin = CTrackingAlgs::vmin, _vmax = CTrackingAlgs::vmax; cv::inRange( hsv, cv::Scalar(0,CTrackingAlgs::smin,MIN(_vmin,_vmax),0), cv::Scalar(180,256,MAX(_vmin,_vmax),0), mask ); std::vector<cv::Mat> vhsv(3); cv::split( hsv, vhsv ); vhsv[0].copyTo(hue); double max_val = 0.f; cv::Mat roi = hue( cv::Range(obj.y, obj.y+obj.height), cv::Range(obj.x, obj.x+obj.width) ); cv::Mat roi_mask= mask( cv::Range(obj.y, obj.y+obj.height), cv::Range(obj.x, obj.x+obj.width) ); cv::calcHist( &roi, 1, CTrackingAlgs::channels, roi_mask, hist, 1, CTrackingAlgs::histSize, CTrackingAlgs::ranges, true, // the histogram is uniform false ); cv::minMaxLoc(hist, 0, &max_val, 0, 0); hist.convertTo(hist, hist.type(), (max_val ? 255. / max_val : 0.), 0); return true; }
Mat PlateLines::customGrayscaleConversion(Mat src) { Mat img_hsv; cvtColor(src,img_hsv,CV_BGR2HSV); Mat grayscale = Mat(img_hsv.size(), CV_8U ); Mat hue(img_hsv.size(), CV_8U ); for (int row = 0; row < img_hsv.rows; row++) { for (int col = 0; col < img_hsv.cols; col++) { int h = (int) img_hsv.at<Vec3b>(row, col)[0]; //int s = (int) img_hsv.at<Vec3b>(row, col)[1]; int v = (int) img_hsv.at<Vec3b>(row, col)[2]; int pixval = pow(v, 1.05); if (pixval > 255) pixval = 255; grayscale.at<uchar>(row, col) = pixval; hue.at<uchar>(row, col) = h * (255.0 / 180.0); } } //displayImage(config, "Hue", hue); return grayscale; }
void hue(huevec& out, int amount, int level) { if (level <= 1) { if (long(out.size()) < amount) out.push_back(0.0); if (long(out.size()) < amount) out.push_back(0.5); } else { hue(out, amount, level - 1); const int lower = out.size(); hue(out, amount, level - 1); const int upper = out.size(); for (int i = lower; i < upper; ++i) out.at(i) += 1.0 / (1 << level); } }
void Weather::Draw() { if(IsPointerNull((void*)engine_m,"Weather::Draw()")) return; if(!running_m) return; // Draw a hue sf::Color col; if(current_weather_type_m == W_RAIN) col = sf::Color::Blue; else if(current_weather_type_m == W_SAND) col = sf::Color::Yellow; else if(current_weather_type_m == W_SNOW) col = sf::Color::White; col.a = 40; sf::RectangleShape hue(sf::Vector2f(640, 480)); hue.setFillColor(col); engine_m->sfml_window_m.draw(hue); for(unsigned int p=0; p<particle_count_m; p++) { particles_m[p].Draw(engine_m); } }
int QgsColorWidget::componentValue( const QgsColorWidget::ColorComponent component ) const { if ( !mCurrentColor.isValid() ) { return -1; } switch ( component ) { case QgsColorWidget::Red: return mCurrentColor.red(); case QgsColorWidget::Green: return mCurrentColor.green(); case QgsColorWidget::Blue: return mCurrentColor.blue(); case QgsColorWidget::Hue: //hue is treated specially, to avoid -1 hues values from QColor for ambiguous hues return hue(); case QgsColorWidget::Saturation: return mCurrentColor.hsvSaturation(); case QgsColorWidget::Value: return mCurrentColor.value(); case QgsColorWidget::Alpha: return mCurrentColor.alpha(); default: return -1; } }
colour hsv_colour::to_rgb() const { double c = value() * saturation(); double h2 = hue() / 60.0; double x = c * (1.0 - std::abs(std::fmod(h2, 2.0) - 1.0)); double r, g, b; if (h2 >= 0.0 && h2 < 1.0) r = c, g = x, b = 0.0; else if (h2 >= 1.0 && h2 < 2.0) r = x, g = c, b = 0.0; else if (h2 >= 2.0 && h2 < 3.0) r = 0.0, g = c, b = x; else if (h2 >= 3.0 && h2 < 4.0) r = 0.0, g = x, b = c; else if (h2 >= 4.0 && h2 < 5.0) r = x, g = 0.0, b = c; else if (h2 >= 5.0 && h2 < 6.0) r = c, g = 0.0, b = x; else r = g = b = 0.0; double m = value() - c; colour result( static_cast<colour::component>(std::floor((r + m) * 255.0)), static_cast<colour::component>(std::floor((g + m) * 255.0)), static_cast<colour::component>(std::floor((b + m) * 255.0)), static_cast<colour::component>(std::floor(alpha() * 255.0))); return result; }
void QgsColorBox::setColor( const QColor &color, const bool emitSignals ) { //check if we need to redraw the box image if ( mComponent == QgsColorWidget::Red && mCurrentColor.red() != color.red() ) { mDirty = true; } else if ( mComponent == QgsColorWidget::Green && mCurrentColor.green() != color.green() ) { mDirty = true; } else if ( mComponent == QgsColorWidget::Blue && mCurrentColor.blue() != color.blue() ) { mDirty = true; } else if ( mComponent == QgsColorWidget::Hue && color.hsvHue() >= 0 && hue() != color.hsvHue() ) { mDirty = true; } else if ( mComponent == QgsColorWidget::Saturation && mCurrentColor.hsvSaturation() != color.hsvSaturation() ) { mDirty = true; } else if ( mComponent == QgsColorWidget::Value && mCurrentColor.value() != color.value() ) { mDirty = true; } QgsColorWidget::setColor( color, emitSignals ); }
void FaceClassifier::nonZeroHueSaturationStatistics(cv::Mat face, FaceData &data) { /* Calculates the average hue and saturation of the face's skin, ignoring * all zeroed pixels while doing this. This is necessary because the mask * we applied zeroed all non-face pixels. */ //split the HSV face image in its 3 channels cv::vector<cv::Mat> faceChannels; cv::split(face, faceChannels); acc::accumulator_set< double, acc::stats<acc::tag::variance> > hue; //accumulates hue acc::accumulator_set< double, acc::stats<acc::tag::variance> > sat; //accumulates saturation acc::accumulator_set< double, acc::stats<acc::tag::variance> > val; //accumulates value /* acc::accumulator_set< double, acc::stats<acc::tag::variance> > blue; //accumulates blue acc::accumulator_set< double, acc::stats<acc::tag::variance> > green; //accumulates green acc::accumulator_set< double, acc::stats<acc::tag::variance> > red; //accumulates red */ double pixelAreaRatio = 0; { int validPixelCount = 0; const int nRows = face.rows; const int nCols = face.cols; for( int i = 0; i < nRows; ++i) { uchar* p_h = faceChannels[0].ptr<uchar>(i); uchar* p_s = faceChannels[1].ptr<uchar>(i); uchar* p_v = faceChannels[2].ptr<uchar>(i); for ( int j = 0; j < nCols; ++j) { if ( p_h[j] ) hue( p_h[j] ); if ( p_s[j] ) sat( p_s[j] ); if ( p_v[j] ) val( p_v[j] ); if ( p_h[j] ) validPixelCount++; } } pixelAreaRatio = (double)validPixelCount / (double)(nRows * nCols); } //only if the face is "made of" non black pixels we have a face if (pixelAreaRatio >= 0.5) { data.skinHueMean = acc::mean(hue); data.skinHueVariance = acc::variance(hue); data.skinSaturationMean = acc::mean(sat); data.skinSaturationVariance = acc::variance(sat); data.skinValueMean = acc::mean(val); data.skinValueVariance = acc::variance(val); } else { data.faceCount = 0; data.skinHueMean = 0; data.skinHueVariance = 0; data.skinSaturationMean = 0; data.skinSaturationVariance = 0; data.skinValueMean = 0; data.skinValueVariance = 0; } }
/*! \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); } }
void hue(huevec& out, int amount) { int level = 0; while ((1 << level) < amount) ++level; out.reserve(amount); hue(out, amount, level); }
bool hsv_colour::operator==(const hsv_colour& aOther) const { return hue() == aOther.hue() && saturation() == aOther.saturation() && value() == aOther.value() && alpha() == aOther.alpha() && hue_undefined() == aOther.hue_undefined(); }
void KHueSaturationSelector::drawPalette( QPixmap *pixmap ) { int xSize = contentsRect().width(), ySize = contentsRect().height(); QImage image( QSize( xSize, ySize ), QImage::Format_RGB32 ); QColor col; int h, s; uint *p; col.setHsv( hue(), saturation(), colorValue() ); int _h, _s, _v, _r, _g, _b; col.getHsv( &_h, &_s, &_v ); col.getRgb( &_r, &_g, &_b ); for ( s = ySize-1; s >= 0; s-- ) { p = ( uint * ) image.scanLine( ySize - s - 1 ); for( h = 0; h < xSize; h++ ) { switch ( chooserMode() ) { case ChooserClassic: default: col.setHsv( 359 * h / ( xSize - 1 ), 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ), 192 ); break; case ChooserHue: col.setHsv( _h, 255 * h / ( xSize - 1 ), 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; case ChooserSaturation: col.setHsv( 359 * h / ( xSize - 1 ), _s, 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; case ChooserValue: col.setHsv( 359 * h / ( xSize - 1 ), 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ), _v ); break; case ChooserRed: col.setRgb( _r, 255 * h / ( xSize - 1 ), 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; case ChooserGreen: col.setRgb( 255 * h / ( xSize - 1 ), _g, 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; case ChooserBlue: col.setRgb( 255 * s / ( ( ySize == 1 ) ? 1 : ySize - 1 ), 255 * h / ( xSize - 1 ), _b ); break; } *p = col.rgb(); p++; } } /* if ( pixmap->depth() <= 8 ) { const QVector<QColor> standardPalette = kdeui_standardPalette(); KImageEffect::dither( image, standardPalette.data(), standardPalette.size() ); } */ *pixmap = QPixmap::fromImage( image ); }
uint8_t DIA_getHue(hue *param, ADM_coreVideoFilter *in) { diaElemFloat hue(&(param->hue),QT_TRANSLATE_NOOP("hue","Hue :"),-180,180); diaElemFloat sat(&(param->saturation),QT_TRANSLATE_NOOP("hue","Sat :"),-180,180); diaElem *elems[]={&hue,&sat}; return diaFactoryRun("Hue",sizeof(elems)/sizeof(diaElem *),elems); }
// from http://www.cs.rit.edu/~ncs/color/t_convert.html FColor HSB::hsbToRgb(const FColor& hsb) { auto h = hue(hsb), s = saturation(hsb), b = brightness(hsb); float red, green, blue; if (s == 0) { // achromatic (grey) red = green = blue = b; } else { h *= 6; // sector 0 to 5 int i = floor(h); auto f = h - i; // factorial part of h auto p = b * (1 - s); auto q = b * (1 - s * f); auto t = b * (1 - s * (1 - f)); switch(i) { case 0: red = b; green = t; blue = p; break; case 1: red = q; green = b; blue = p; break; case 2: red = p; green = b; blue = t; break; case 3: red = p; green = q; blue = b; break; case 4: red = t; green = p; blue = b; break; case 5: default: red = b; green = p; blue = q; break; } } return FColor(red, green, blue, hsb.alpha()); }
void QgsColorWheel::setColor( const QColor &color, const bool emitSignals ) { if ( color.hue() >= 0 && color.hue() != hue() ) { //hue has changed, need to redraw the triangle mTriangleDirty = true; } QgsColorWidget::setColor( color, emitSignals ); }
void ColorBox::setCurrent(int x, int y) { QColor newColor; x = clamp(x, 0, 120); y = clamp(y, 0, 120); int oldAlpha = m_color.alpha(); newColor.setHsv(hue(), (x*255) / 120, 255 - (y*255) / 120); newColor.setAlpha(oldAlpha); setColor(newColor); }
void ColorBox::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter p(this); if ((m_color.saturation()>1) && (m_color.value()>1)) m_saturatedColor.setHsv(m_color.hsvHue(),255,255); if ((hue() != m_lastHue) || (m_cache.isNull())) { m_lastHue = hue(); int fixedHue = clamp(m_lastHue, 0, 359); QImage cache = QImage(120, 120, QImage::Format_RGB32); int height = 120; int width = 120; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { QColor c; c.setHsv(fixedHue, (x*255) / width, 255 - (y*255) / height); cache.setPixel(x, y, c.rgb()); } } m_cache = QPixmap::fromImage(cache); } p.drawPixmap(5, 5, m_cache); int x = clamp(m_color.hsvSaturationF() * 120, 0, 119) + 5; int y = clamp(120 - m_color.valueF() * 120, 0, 119) + 5; p.setPen(QColor(255, 255, 255, 50)); p.drawLine(5, y, x-1, y); p.drawLine(x+1, y, width()-7, y); p.drawLine(x, 5, x, y-1); p.drawLine(x, y+1, x, height()-7); }
QColor IconColors::dominantColor() const { const QImage img = m_icon.pixmap({32, 32}).toImage(); if(img.isNull()) { qWarning() << "wrong icon" << m_icon << m_icon.name(); return QColor(Qt::black); } const int tolerance = 10; QVector<uint> hue(360/tolerance, 0); #ifdef OUTPUT_PIXMAP_DEBUG QImage thing(img.size()+QSize(0,1), QImage::Format_ARGB32); thing.fill(Qt::white); #endif for (int w=0, cw=img.width(); w<cw; ++w) { for (int h=0, ch=img.height(); h<ch; ++h) { #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) const QColor c = img.pixelColor(w, h).toHsv(); #else const QColor c(img.pixel(w, h)); #endif if (c.value()>150 && c.saturation()>20 && c.hue()>=0 && c.alpha()>200) { hue[c.hue()/tolerance]++; #ifdef OUTPUT_PIXMAP_DEBUG // qDebug() << "adopting" << w << "x" << h << c.name() << c.hue(); // thing.setPixelColor(w, h, c); thing.setPixelColor(w, h, QColor::fromHsv(tolerance*(c.hue()/tolerance), 220, 220)); #endif } } } uint dominantHue = 0, biggestAmount = 0; for(int i=0; i<hue.size(); ++i) { if (hue[i]>biggestAmount) { biggestAmount = hue[i]; dominantHue = i; } } QColor ret = QColor::fromHsv((dominantHue*tolerance + tolerance/2) % 360, 255, 255); #ifdef OUTPUT_PIXMAP_DEBUG qDebug() << "dominant" << dominantHue << hue[dominantHue] << "~=" << ((100*hue[dominantHue])/(img.width()*img.height())) << "% " << iconName(); thing.setPixelColor(0, img.height(), ret); thing.save("/tmp/"+iconName()+".png"); #endif return ret; }
void RainbowMode::step(Adafruit_NeoPixel* pixels) { if (rainbowState < 0) { rainbowState = 256*5; } for(int i=0; i< NUMPIXELS; i++) { uint32_t color = hue(((i * 256 / NUMPIXELS) + rainbowState) & 255); pixels->setPixelColor(i, color); } rainbowState--; }
std::vector<wxColour>& GetBigFixColoursPalette( int numteams ) { static std::vector<wxColour> result; wxLogDebugFunc( TowxString(numteams) ); huevec huevector; static int satvalbifurcatepos; static std::vector<double> satvalsplittings; if ( satvalsplittings.empty() ) // insert ranges to bifurcate { satvalsplittings.push_back( 1 ); satvalsplittings.push_back( 0 ); satvalbifurcatepos = 0; } hue( huevector, numteams ); int bisectionlimit = 20; for ( int i = result.size(); i < numteams; i++ ) { double hue = huevector[i]; double saturation = 1; double value = 1; int switccolors = i % 3; // why only 3 and not all combinations? because it's easy, plus the bisection limit cannot be divided integer by it if ( ( i % bisectionlimit ) == 0 ) { satvalbifurcatepos = satvalbifurcatepos % ( satvalsplittings.size() -1 ); std::vector<double>::iterator toinsert = satvalsplittings.begin() + satvalbifurcatepos + 1; satvalsplittings.insert( toinsert, ( satvalsplittings[satvalbifurcatepos] - satvalsplittings[satvalbifurcatepos + 1] ) / 2 + satvalsplittings[satvalbifurcatepos + 1] ); satvalbifurcatepos += 2; } if ( switccolors == 1 ) { saturation = satvalsplittings[satvalbifurcatepos -1]; } else if ( switccolors == 2 ) { value = satvalsplittings[satvalbifurcatepos -1]; } hue += 0.17; // use as starting point a zone where color band is narrow so that small variations means high change in visual effect if ( hue > 1 ) hue-= 1; wxImage::HSVValue hsvcolor( hue, saturation, value ); wxImage::RGBValue rgbvalue = wxImage::HSVtoRGB( hsvcolor ); wxColour col( rgbvalue.red, rgbvalue.green, rgbvalue.blue ); result.push_back( col ); } return result; }
void updateHSX() override { float r = qBound(0.0f, rgb(0), 1.0f); float g = qBound(0.0f, rgb(1), 1.0f); float b = qBound(0.0f, rgb(2), 1.0f); float h = ::getHue(r, g, b); float x = ::getLightness<HSXType>(r, g, b); KisColor::VecRGB hue(0.0, 0.0, 0.0); ::getRGB(hue(0), hue(1), hue(2), h); ::setLightness<HSXType>(hue(0), hue(1), hue(2), x); KisColor::VecRGB diff1 = hue - KisColor::VecRGB(x,x,x); KisColor::VecRGB diff2 = rgb - KisColor::VecRGB(x,x,x); hsx(0) = h; hsx(1) = diff1.dot(diff2) / diff1.squaredNorm(); // project rgb onto (VecRGB(x,x,x) - hue) hsx(2) = x; }
void ItemPinned::paintEvent(QPaintEvent *paintEvent) { const auto *parent = parentWidget(); auto color = parent->palette().color(QPalette::Background); const int lightThreshold = 100; const bool menuBackgrounIsLight = color.lightness() > lightThreshold; color.setHsl( color.hue(), color.saturation(), qMax(0, qMin(255, color.lightness() + (menuBackgrounIsLight ? -200 : 50))) ); QPainter painter(this); const int border = pointsToPixels(6); const QRect rect(width() - border, 0, width(), height()); painter.setOpacity(0.15); painter.fillRect(rect, color); QWidget::paintEvent(paintEvent); }
void BandwidthGui::handleClickedLegend(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) { QCPPlottableLegendItem* graphItem = dynamic_cast<QCPPlottableLegendItem*>(item); if(!graphItem) return; auto color = graphItem->plottable()->brush().color(); auto hue = color.hue() + 180 % 360; auto sat = color.saturation(); auto val = color.value(); if(sat == BRUSH_SATURATION) { sat = 255; val = 255; } else { sat = BRUSH_SATURATION; val = BRUSH_VALUE; } color.setHsv(hue, sat, val); graphItem->plottable()->setBrush(QBrush(color)); }
//------------------------------------------------------------------------------ // serialize() -- print the value of this object to the output stream sout. //------------------------------------------------------------------------------ std::ostream& Hsv::serialize(std::ostream& sout, const int i, const bool slotsOnly) const { int j = 0; if ( !slotsOnly ) { sout << "( " << getFactoryName() << std::endl; j = 4; } indent(sout,i+j); sout << "hue: " << hue() << std::endl; indent(sout,i+j); sout << "saturation: " << saturation() << std::endl; indent(sout,i+j); sout << "value: " << value() << std::endl; if ( !slotsOnly ) { indent(sout,i); sout << ")" << std::endl; } return sout; }
cv::Mat VisionTask::generateHueMap(cv::Mat rgb) { cv::Mat hue(height, width, CV_16SC1); for (int i = 0; i < height*width; i++) { unsigned char* rgb_data = (unsigned char*)rgb.data + i*3; int16_t* hue_data = (int16_t*)hue.data + i*3; unsigned char r = rgb_data[2]; unsigned char g = rgb_data[1]; unsigned char b = rgb_data[0]; if (r == g && g == b) { *hue_data = -1; } if (r >= b) { if (r >= g) { if (g >= b) { // red-yellow *hue_data = 60*(g-b)/(r-b); } else { // magenta-red *hue_data = 360 - 60*(b-g)/(r-g); } } else { // yellow-green *hue_data = 120 - 60*(r-b)/(g-b); } } else { if (b >= g) { if (g >= r) { // cyan-blue *hue_data = 240 - 60*(g-r)/(b-r); } else { // blue-magenta *hue_data = 240 + 60*(r-g)/(b-g); } } else { // green-cyan *hue_data = 120 + 60*(b-r)/(g-r); } } } return hue; }
JNIEXPORT void JNICALL Java_com_lightcrafts_jai_opimage_ColorSelectionMaskOpImage_nativeUshortLoop (JNIEnv *env, jobject cls, jshortArray jsrcData, jbyteArray jdstData, jint width, jint height, jintArray jsrcBandOffsets, jint dstOffset, jint srcLineStride, jint dstLineStride, jfloatArray jcolorSelection, jfloat wr, jfloat wg, jfloat wb) { ushort *srcData = (ushort *) env->GetPrimitiveArrayCritical(jsrcData, 0); byte *dstData = (byte *) env->GetPrimitiveArrayCritical(jdstData, 0); int *srcBandOffsets = (int *) env->GetPrimitiveArrayCritical(jsrcBandOffsets, 0); float *colorSelection = (float *) env->GetPrimitiveArrayCritical(jcolorSelection, 0); int srcROffset = srcBandOffsets[0]; int srcGOffset = srcBandOffsets[1]; int srcBOffset = srcBandOffsets[2]; float hueLower = colorSelection[0]; float hueLowerFeather = colorSelection[1]; float hueUpper = colorSelection[2]; float hueUpperFeather = colorSelection[3]; float luminosityLower = colorSelection[4]; float luminosityLowerFeather = colorSelection[5]; float luminosityUpper = colorSelection[6]; float luminosityUpperFeather = colorSelection[7]; int hueOffset = 0; if (hueLower < 0 || hueLower - hueLowerFeather < 0 || hueUpper < 0) { hueLower += 1; hueUpper += 1; hueOffset = 1; } else if (hueLower > 1 || hueUpper + hueUpperFeather > 1 || hueUpper > 1) { hueOffset = -1; } for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { float r = srcData[3 * col + row * srcLineStride + srcROffset]; float g = srcData[3 * col + row * srcLineStride + srcGOffset]; float b = srcData[3 * col + row * srcLineStride + srcBOffset]; // float hue = hue(r / (float) 0xffff, g / (float) 0xffff, b / (float) 0xffff) / (float) (2 * Math.PI); float cmax = (r > g) ? r : g; if (b > cmax) cmax = b; float cmin = (r < g) ? r : g; if (b < cmin) cmin = b; float saturation; if (cmax != 0) saturation = (cmax - cmin) / cmax; else saturation = 0; #if defined(__ppc__) float luminosity = (float) (log1pf((wr * r + wg * g + wb * b)/0x100) / (8 * logf(2))); #else float luminosity = (float) (fast_log2((wr * r + wg * g + wb * b)/0x100) / 8); #endif float luminosityMask, colorMask; const float stmin = 0.01f; const float stmax = 0.02f; const float ltmin = .01; const float ltmax = .02; if (saturation > stmin && luminosity > ltmin) { float h = hue(r, g, b) / (float) (2 * M_PI); if (hueOffset == 1 && h < hueLower - hueLowerFeather) h += 1; else if (hueOffset == -1 && h < 0.5) h += 1; if (h >= hueLower && h <= hueUpper) colorMask = 1; else if (h >= (hueLower - hueLowerFeather) && h < hueLower) colorMask = (h - (hueLower - hueLowerFeather))/hueLowerFeather; else if (h > hueUpper && h <= (hueUpper + hueUpperFeather)) colorMask = (hueUpper + hueUpperFeather - h)/hueUpperFeather; else colorMask = 0; if (saturation < stmax) colorMask *= (saturation - stmin) / (stmax - stmin); if (luminosity < ltmax) colorMask *= (luminosity - ltmin) / (ltmax - ltmin); } else colorMask = 0; if (luminosity >= luminosityLower && luminosity <= luminosityUpper) luminosityMask = 1; else if (luminosity >= (luminosityLower - luminosityLowerFeather) && luminosity < luminosityLower) luminosityMask = (luminosity - (luminosityLower - luminosityLowerFeather))/luminosityLowerFeather; else if (luminosity > luminosityUpper && luminosity <= (luminosityUpper + luminosityUpperFeather)) luminosityMask = (luminosityUpper + luminosityUpperFeather - luminosity)/luminosityUpperFeather; else luminosityMask = 0; colorMask *= luminosityMask; dstData[col + row * dstLineStride + dstOffset] = (byte) (0xff * colorMask); } } env->ReleasePrimitiveArrayCritical(jsrcData, srcData, 0); env->ReleasePrimitiveArrayCritical(jdstData, dstData, 0); env->ReleasePrimitiveArrayCritical(jsrcBandOffsets, srcBandOffsets, 0); env->ReleasePrimitiveArrayCritical(jcolorSelection, colorSelection, 0); }
std::string ColorDiscriminator::HueDominator::hue_str() const { return HueToString(hue()); }
void KColorValueSelector::drawPalette( QPixmap *pixmap ) { int xSize = contentsRect().width(), ySize = contentsRect().height(); QImage image( QSize( xSize, ySize ), QImage::Format_RGB32 ); QColor col; uint *p; QRgb rgb; int _r, _g, _b; col.setHsv( hue(), saturation(), colorValue() ); col.getRgb( &_r, &_g, &_b ); if ( orientation() == Qt::Horizontal ) { for ( int v = 0; v < ySize; v++ ) { p = ( uint * ) image.scanLine( ySize - v - 1 ); for( int x = 0; x < xSize; x++ ) { switch ( chooserMode() ) { case ChooserClassic: default: col.setHsv( hue(), saturation(), 255 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ) ); break; case ChooserRed: col.setRgb( 255 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ), _g, _b ); break; case ChooserGreen: col.setRgb( _r, 255 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ), _b ); break; case ChooserBlue: col.setRgb( _r, _g, 255 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ) ); break; case ChooserHue: col.setHsv( 360 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ), 255, 255 ); break; case ChooserSaturation: col.setHsv( hue(), 255 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ), colorValue() ); break; case ChooserValue: col.setHsv( hue(), saturation(), 255 * x / ( ( xSize == 1 ) ? 1 : xSize - 1 ) ); break; } rgb = col.rgb(); *p++ = rgb; } } } if( orientation() == Qt::Vertical ) { for ( int v = 0; v < ySize; v++ ) { p = ( uint * ) image.scanLine( ySize - v - 1 ); switch ( chooserMode() ) { case ChooserClassic: default: col.setHsv( hue(), saturation(), 255 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; case ChooserRed: col.setRgb( 255 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ), _g, _b ); break; case ChooserGreen: col.setRgb( _r, 255 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ), _b ); break; case ChooserBlue: col.setRgb( _r, _g, 255 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; case ChooserHue: col.setHsv( 360 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ), 255, 255 ); break; case ChooserSaturation: col.setHsv( hue(), 255 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ), colorValue() ); break; case ChooserValue: col.setHsv( hue(), saturation(), 255 * v / ( ( ySize == 1 ) ? 1 : ySize - 1 ) ); break; } rgb = col.rgb(); for ( int i = 0; i < xSize; i++ ) *p++ = rgb; } } /* if ( pixmap->depth() <= 8 ) { extern QVector<QColor> kdeui_standardPalette(); const QVector<QColor> standardPalette = kdeui_standardPalette(); KImageEffect::dither( image, standardPalette.data(), standardPalette.size() ); } */ *pixmap = QPixmap::fromImage( image ); }
void QgsColorWheel::createTriangle() { if ( !mWheelImage || !mTriangleImage ) { return; } QPointF center = QPointF( mWheelImage->width() / 2.0, mWheelImage->height() / 2.0 ); mTriangleImage->fill( Qt::transparent ); QPainter imagePainter( mTriangleImage ); imagePainter.setRenderHint( QPainter::Antialiasing ); int angle = hue(); double wheelRadius = mWheelImage->width() / 2.0; double triangleRadius = wheelRadius - mWheelThickness - 1; //pure version of hue (at full saturation and value) QColor pureColor = QColor::fromHsv( angle, 255, 255 ); //create copy of color but with 0 alpha QColor alphaColor = QColor( pureColor ); alphaColor.setAlpha( 0 ); //some rather ugly shortcuts to obtain corners and midpoints of triangle QLineF line1 = QLineF( center.x(), center.y(), center.x() - triangleRadius * cos( M_PI / 3.0 ), center.y() - triangleRadius * sin( M_PI / 3.0 ) ); QLineF line2 = QLineF( center.x(), center.y(), center.x() + triangleRadius, center.y() ); QLineF line3 = QLineF( center.x(), center.y(), center.x() - triangleRadius * cos( M_PI / 3.0 ), center.y() + triangleRadius * sin( M_PI / 3.0 ) ); QLineF line4 = QLineF( center.x(), center.y(), center.x() - triangleRadius * cos( M_PI / 3.0 ), center.y() ); QLineF line5 = QLineF( center.x(), center.y(), ( line2.p2().x() + line1.p2().x() ) / 2.0, ( line2.p2().y() + line1.p2().y() ) / 2.0 ); line1.setAngle( line1.angle() + angle ); line2.setAngle( line2.angle() + angle ); line3.setAngle( line3.angle() + angle ); line4.setAngle( line4.angle() + angle ); line5.setAngle( line5.angle() + angle ); QPointF p1 = line1.p2(); QPointF p2 = line2.p2(); QPointF p3 = line3.p2(); QPointF p4 = line4.p2(); QPointF p5 = line5.p2(); //inspired by Tim Baumann's work at https://github.com/timjb/colortriangle/blob/master/colortriangle.js QLinearGradient colorGrad = QLinearGradient( p4.x(), p4.y(), p2.x(), p2.y() ); colorGrad.setColorAt( 0, alphaColor ); colorGrad.setColorAt( 1, pureColor ); QLinearGradient whiteGrad = QLinearGradient( p3.x(), p3.y(), p5.x(), p5.y() ); whiteGrad.setColorAt( 0, QColor( 255, 255, 255, 255 ) ); whiteGrad.setColorAt( 1, QColor( 255, 255, 255, 0 ) ); QPolygonF triangle; triangle << p2 << p1 << p3 << p2; imagePainter.setPen( Qt::NoPen ); //start with a black triangle imagePainter.setBrush( QBrush( Qt::black ) ); imagePainter.drawPolygon( triangle ); //draw a gradient from transparent to the pure color at the triangle's tip imagePainter.setBrush( QBrush( colorGrad ) ); imagePainter.drawPolygon( triangle ); //draw a white gradient using additive composition mode imagePainter.setCompositionMode( QPainter::CompositionMode_Plus ); imagePainter.setBrush( QBrush( whiteGrad ) ); imagePainter.drawPolygon( triangle ); //above process results in some small artifacts on the edge of the triangle. Let's clear these up //use source composition mode and draw an outline using a transparent pen //this clears the edge pixels and leaves a nice smooth image imagePainter.setCompositionMode( QPainter::CompositionMode_Source ); imagePainter.setBrush( Qt::NoBrush ); imagePainter.setPen( QPen( Qt::transparent ) ); imagePainter.drawPolygon( triangle ); imagePainter.end(); mTriangleDirty = false; }