एक 2d हिस्टोग्राम ड्राइंग opencv



image-processing histogram (1)

क्या आपका मतलब कुछ ऐसा था?

  • यह एचएसवी हिस्टोग्राम को 3 डी ग्राफ के रूप में दिखाया गया है
  • V को 3D पर जाने के लिए अनदेखा किया जाता है (अन्यथा यह 4D ग्राफ होगा ...)

यदि हाँ, तो यह कैसे करना है (मैं OpenCV का उपयोग नहीं करता हूं, इसलिए इसे अपनी आवश्यकताओं के अनुसार समायोजित करें):

  1. स्रोत छवि को एचएसवी में बदलें
  2. V मूल्य की अनदेखी हिस्टोग्राम की गणना
    • एक ही एच, एस के साथ सभी रंगों को एकल रंग माना जाता है, चाहे कोई भी वी हो
    • आप किसी भी अन्य को अनदेखा कर सकते हैं लेकिन वी पैरामीटर सबसे अच्छा विकल्प लगता है
  3. ग्राफ खींचना

    • पहले गहरे रंग के साथ दीर्घवृत्त ड्रा करें (HSV बेस डिस्क)
    • फिर प्रत्येक बिंदु के लिए संबंधित हिस्टोग्राम मूल्य लेते हैं और उज्जवल रंग के साथ ऊर्ध्वाधर रेखा खींचते हैं। लाइन का आकार हिस्टोग्राम मूल्य के लिए आनुपातिक है

यहाँ C ++ कोड है जो मैंने इसके साथ किया है:

picture pic0,pic1,pic2,zed;

int his[65536];
DWORD w;

int h,s,v,x,y,z,i,n;
double r,a;
color c;

// compute histogram (ignore v)
pic2=pic0;                      // copy input image pic0 to pic2
pic2.rgb2hsv();                 // convert to HSV
for (x=0;x<65536;x++) his[x]=0; // clear histogram
for (y=0;y<pic2.ys;y++)         // compute it
 for (x=0;x<pic2.xs;x++)
    {
    c=pic2.p[y][x];
    h=c.db[picture::_h];
    s=c.db[picture::_s];
    w=h+(s<<8);                 // form 16 bit number from 24bit HSV color
    his[w]++;                   // update color usage count ...
    }
for (n=0,x=0;x<65536;x++) if (n<his[x]) n=his[x];   // max probability

// draw the colored HSV base plane and histogram
zed =pic1; zed .clear(999); // zed buffer for 3D
           pic1.clear(0);   // image of histogram
for (h=0;h<255;h++)
 for (s=0;s<255;s++)
    {
    c.db[picture::_h]=h;
    c.db[picture::_s]=s;
    c.db[picture::_v]=100;      // HSV base darker
    c.db[picture::_a]=0;
    x=pic1.xs>>1;               // HSV base disc position centers on the bottom
    y=pic1.ys-100;
    a=2.0*M_PI*double(h)/256.0; // disc -> x,y
    r=double(s)/256.0;
    x+=120.0*r*cos(a);          // elipse for 3D ilusion
    y+= 50.0*r*sin(a);
    z=-y;
    if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x++;
    if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y++;
    if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x--;
    if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y--;

    w=h+(s<<8);                 // get histogram index for this color
    i=((pic1.ys-150)*his[w])/n;
    c.db[picture::_v]=255;      // histogram brighter
    for (;(i>0)&&(y>0);i--,y--)
        {
        if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x++;
        if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y++;
        if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } x--;
        if (zed.p[y][x].dd>=z){ pic1.p[y][x]=c; zed.p[y][x].dd=z; } y--;
        }
    }
pic1.hsv2rgb();                 // convert to RGB to see correct colors
  • इनपुट छवि pic0 (गुलाब), आउटपुट छवि pic1 (हिस्टोग्राम ग्राफ) है
  • pic2 हिस्टोग्राम अभिकलन के लिए pic0 को HSV में परिवर्तित किया गया है
  • zed जेड छँटाई से बचने के लिए 3 डी प्रदर्शन के लिए जेड बफर है ...

मैं छवियों के लिए अपने स्वयं के चित्र वर्ग का उपयोग करता हूं इसलिए कुछ सदस्य हैं:

  • पिक्सेल में छवि का xs,ys आकार
  • p[y][x].dd पिक्सेल है (x, y) 32 बिट पूर्णांक प्रकार के रूप में
  • clear(color) - पूरी छवि को साफ करता है
  • resize(xs,ys) - नए रिज़ॉल्यूशन में छवि का आकार बदलता है
  • rgb2hsv() और hsv2rgb() ... लगता है कि यह क्या करता है :)

[संपादित करें] आपका 2 डी हिस्टोग्राम

ऐसा लगता है कि आपने 2 डी सरणी में रंग कोडित किया है। एक अक्ष H और दूसरा S । तो आपको सरणी पते से H,S मान की गणना करने की आवश्यकता है। यदि यह रैखिक है तो HSV[i][j] :

  • H=h0+(h1-h0)*i/maxi
  • S=s0+(s1-s0)*j/maxj
  • या i,j उलट गया
  • h0,h1,s0,s1 रंग पर्वतमाला हैं
  • maxi,maxj सरणी आकार हैं

जैसा कि आप देख सकते हैं कि आप भी मेरी तरह V त्याग सकते हैं इसलिए अब आपके पास H,S हिस्टोग्राम 2 डी सरणी में प्रत्येक सेल के लिए है। जहां संभावना सेल वैल्यू है। अब यदि आप एक छवि बनाना चाहते हैं, तो आपको यह पता होना चाहिए कि इसे कैसे आउटपुट किया जाए (2 डी ग्राफ, 3 डी, मैपिंग, ...)। अनियोजित 2D ग्राफ़ ड्राफ़्ट ग्राफ़ के लिए जहाँ:

  • x=i+maj*i
  • y=HSV[i][j]
  • color=(H,S,V=200);

यदि आप इसे क्रमबद्ध करना चाहते हैं तो बस x अक्ष की गणना अलग से करें या 2 डी सरणी को क्रमबद्ध क्रम में लूप करें और x केवल वेतन वृद्धि

[edit2] कोड और कुछ छवियों का अद्यतन

मैंने ऊपर C ++ कोड की मरम्मत की है (गलत Z मान चिह्न, Z बफर स्थिति को बदला और अच्छे आउटपुट के लिए बड़े बिंदु जोड़े)। आपके 2 डी सरणी रंग इस प्रकार हो सकते हैं:

जहां एक अक्ष / सूचकांक H , तो दूसरा S और Value निर्धारित है (मैं 200 का चयन करता हूं)। अगर आपके एक्साइज की अदला-बदली हो जाती है, तो बस y=x आइना समझें ...

रंग छँटाई वास्तव में सिर्फ एक आदेश है जिसमें आप सभी रंगों को सरणी से लेते हैं। उदाहरण के लिए:

v=200; x=0;
for (h=0;h<256;h++)
 for (s=0;s<256;s++,x++)
 {
 y=HSV[h][s];
 // here draw line (x,0)->(x,y) by color hsv2rgb(h,s,v); 
 }

यह वेतन वृद्धि का तरीका है। आप अलग-अलग छँटाई को प्राप्त करने के लिए H,S से x गणना कर सकते हैं या fors स्वैप कर fors ( x++ को आंतरिक लूप में होना चाहिए)

यदि आप आरजीबी हिस्टोग्राम प्लॉट चाहते हैं तो देखें:

  • कैसे उद्देश्य सी के साथ छवि के आरजीबी रंग हिस्टोग्राम साजिश करने के लिए

मैं सोच रहा हूँ कि opencv c ++ में HSV Mat के 2d हिस्टोग्राम की साजिश कैसे की जाए। मेरा वर्तमान कोड यह प्रदर्शित करने का प्रयास बुरी तरह विफल रहता है। मैंने हिस्टोग्राम्स को प्लॉट करने के तरीके के बारे में देखा है और मैंने जो भी पाया है, वे उन्हें स्वतंत्र 1 डी हिस्टोग्राम के रूप में प्लॉट कर रहे थे।

यहां मेरे वर्तमान आउटपुट में ह्यू बिन्स की संख्या 30 है और संतृप्ति डिब्बे 32 है।

यहां एक अन्य आउटपुट है जिसमें ह्यू के डिब्बे की संख्या 7 और संतृप्ति के डिब्बे की संख्या 5 है।

मैं चाहूंगा कि यह यहां के परिणाम की तरह दिखे

http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html

मैंने यह भी देखा कि जब भी मैं cout करता हूं << Hist.size यह मुझे 50x50 देता है। क्या मैं यह समझ सकता हूँ कि सरणी का पहला आयाम 250 आकार का है?

इसके अलावा, एक हिस्टोग्राम को उच्चतम से निम्नतम (या इसके विपरीत) मूल्य आवृत्ति में कैसे क्रमबद्ध करता है? यह एक और समस्या है जिसे मैं हल करने की कोशिश कर रहा हूं।

मेरा वर्तमान कार्य निम्नानुसार है।

void Perform_Hist(Mat& MeanShift, Mat& Pyramid_Result, Mat& BackProj){  

  Mat HSV, Hist;

  int histSize[] = {hbins, sbins};
  int channels[] = {0, 1};

  float hranges[] = {0, 180};
  float sranges[] = {0, 256};

  const float* ranges[] = {hranges, sranges};

  cvtColor(MeanShift, HSV, CV_BGR2HSV);

  Mat PyrGray = Pyramid_Result.clone();

  calcHist(&HSV, 1, channels, Mat(), Hist, 2, histSize, ranges, true, false); 
  normalize(Hist, Hist, 0, 255, NORM_MINMAX, -1, Mat());  
  invert(Hist, Hist, 1);  
  calcBackProject(&PyrGray, 1, channels, Hist, BackProj, ranges, 1, true);

  double maxVal = 0; minMaxLoc(Hist, 0, &maxVal, 0, 0);

  int scale = 10;
  Mat histImage = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);

  for(int i = 1; i < hbins * sbins; i++){
     line(histImage,
     Point(hbins*sbins*(i-1), sbins - cvRound(Hist.at<float>(i-1))),
     Point(hbins*sbins*(i-1), sbins - cvRound(Hist.at<float>(i))),
     Scalar(255,0,0), 2, 8, 0);
  }
  imshow (HISTOGRAM, histImage);
}




histogram