2010-06-25 12 views
6

में किसी छवि के विपरीत समायोजित करें क्या सी # में किसी छवि के विपरीत को समायोजित करने का कोई प्रभावी तरीका है?सी # कुशलता से

मैंने this article देखा है जो प्रति-पिक्सेल ऑपरेशन करने की वकालत करता है। जल्दी नहीं

मैं पहले से ही स्थानों में रंग मैट्रिस का उपयोग कर रहा हूं और उन्हें त्वरित होने के लिए ढूंढ रहा हूं। क्या उनका उपयोग करके कंट्रास्ट समायोजित करने का कोई तरीका है? (नोट: This guy इसे गलत हो जाता है।)

मैं भी EmguCV का उपयोग कर रहा हूं। मैंने देखा कि ओपनसीवी (जो इमू लपेटें) seems to have a contrast function - क्या इमू के माध्यम से इसका उपयोग करने का कोई तरीका है? फिलहाल मैं इगू में ऐसा कर सकता हूं जो हिस्टोग्राम को सामान्यीकृत करता है, जो इसके विपरीत पर नियंत्रण की किसी भी डिग्री के साथ नहीं बल्कि विपरीतता को बदलता है।

किसी को भी कोई विचार है?

+0

तुम क्यों करते हैं का कहना है कि " वह आदमी "यह गलत हो जाता है? – DkAngelito

+0

@ डीकेएंजेलिटो वाह, यह बहुत समय पहले से है। यदि मेमोरी परोसता है, तो कलरमैट्रिक्स दृष्टिकोण मध्य-बिंदुओं के मूल्यों को दूर/स्थानांतरित नहीं कर सकता है, जो वास्तव में एक कंट्रास्ट एडजस्टमेंट है। यदि यह मदद करता है, तो नीचे MusicGenesis द्वारा स्वीकृत उत्तर ने सर्वसम्मति के रूप में सर्वसम्मति को आकर्षित किया है। –

+0

"यह लड़का" लिंक अब टूटा हुआ है। – Chad

उत्तर

26

कि नमूने में कोड आप के लिए काम करता है, तो आप इसे बड़े पैमाने पर (परिमाण के आदेश द्वारा) Bitmap.LockBits है, जो एक BitmapData उद्देश्य यह है कि संकेत के माध्यम से बिटमैप के पिक्सेल डेटा तक पहुँच की अनुमति देता है रिटर्न का उपयोग करके गति कर सकते हैं। वेब पर और स्टैक ओवरफ्लो पर कई नमूने हैं जो दिखाते हैं कि लॉकबिट का उपयोग कैसे करें।

Bitmap.SetPixel() और Bitmap.GetPixel() मानव जाति के लिए जाने वाली सबसे धीमी विधियां हैं, और वे दोनों Color कक्षा का उपयोग करते हैं, जो मानव जाति के लिए सबसे धीमी कक्षा है। उन्हें अवांछित डेवलपर्स को चेतावनी के रूप में Bitmap.GetPixelAndByGodYoullBeSorryYouDid() और Bitmap.SetPixelWhileGettingCoffee नामित किया जाना चाहिए था।

अद्यतन: आपको लगता है कि नमूने में कोड को संशोधित करने जा रहे हैं, ध्यान दें कि यह हिस्सा:

Bitmap NewBitmap = (Bitmap)Image.Clone(); 

अद्यतन 2:

System.Drawing.Bitmap TempBitmap = Image; 
System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, 
    TempBitmap.Height); 
System.Drawing.Graphics NewGraphics = 
    System.Drawing.Graphics.FromImage(NewBitmap); 
NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, 
    TempBitmap.Width, TempBitmap.Height), 
    new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 
    System.Drawing.GraphicsUnit.Pixel); 
NewGraphics.Dispose(); 

इस के साथ बदला जा सकता है: एडजस्ट कंट्रास्ट विधि (कुछ अन्य गति सुधारों के साथ) का लॉकबिट संस्करण यहां है:

public static Bitmap AdjustContrast(Bitmap Image, float Value) 
{ 
    Value = (100.0f + Value)/100.0f; 
    Value *= Value; 
    Bitmap NewBitmap = (Bitmap)Image.Clone(); 
    BitmapData data = NewBitmap.LockBits(
     new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), 
     ImageLockMode.ReadWrite, 
     NewBitmap.PixelFormat); 
    int Height = NewBitmap.Height; 
    int Width = NewBitmap.Width; 

    unsafe 
    { 
     for (int y = 0; y < Height; ++y) 
     { 
      byte* row = (byte*)data.Scan0 + (y * data.Stride); 
      int columnOffset = 0; 
      for (int x = 0; x < Width; ++x) 
      { 
       byte B = row[columnOffset]; 
       byte G = row[columnOffset + 1]; 
       byte R = row[columnOffset + 2]; 

       float Red = R/255.0f; 
       float Green = G/255.0f; 
       float Blue = B/255.0f; 
       Red = (((Red - 0.5f) * Value) + 0.5f) * 255.0f; 
       Green = (((Green - 0.5f) * Value) + 0.5f) * 255.0f; 
       Blue = (((Blue - 0.5f) * Value) + 0.5f) * 255.0f; 

       int iR = (int)Red; 
       iR = iR > 255 ? 255 : iR; 
       iR = iR < 0 ? 0 : iR; 
       int iG = (int)Green; 
       iG = iG > 255 ? 255 : iG; 
       iG = iG < 0 ? 0 : iG; 
       int iB = (int)Blue; 
       iB = iB > 255 ? 255 : iB; 
       iB = iB < 0 ? 0 : iB; 

       row[columnOffset] = (byte)iB; 
       row[columnOffset + 1] = (byte)iG; 
       row[columnOffset + 2] = (byte)iR; 

       columnOffset += 4; 
      } 
     } 
    } 

    NewBitmap.UnlockBits(data); 

    return NewBitmap; 
} 

नोट: इस कोड को using System.Drawing.Imaging; आपकी कक्षा में 'विवरणों का उपयोग करके' की आवश्यकता है, और इसके लिए यह आवश्यक है कि प्रोजेक्ट के allow unsafe code विकल्प को जांचें (प्रोजेक्ट के लिए बिल्ड प्रॉपर्टी टैब पर)।

पिक्सेल-बाय-पिक्सेल ऑपरेशंस के लिए गेट पिक्सेल और सेटपिक्सेल इतनी धीमी है कि विधि कॉल का ओवरहेड स्वयं ही एक बड़ा कारक बनना शुरू कर देता है। आम तौर पर, यहां मेरे कोड नमूने को रिफैक्टरिंग के लिए उम्मीदवार माना जाएगा, क्योंकि आप अपने स्वयं के सेटपिक्सेल और गेट पिक्सेल विधियों को लिख सकते हैं जो मौजूदा बिटमैपडाटा ऑब्जेक्ट का उपयोग करते हैं, लेकिन फ़ंक्शन के अंदर गणित के लिए प्रोसेसिंग समय विधि ओवरहेड से बहुत छोटा होगा प्रत्येक कॉल का। यही कारण है कि मैंने मूल विधि में Clamp कॉल को भी हटा दिया।

इसे गति देने का एक और तरीका यह केवल एक "विनाशकारी" फ़ंक्शन बनाना होगा, और प्रतिलिपि बनाने और संशोधित प्रति को वापस करने के बजाय पास बिटमैप पैरामीटर को संशोधित करना होगा।

+2

मैं इसे लेता हूं आप नामकरण सामग्री के प्रभारी हैं जहां आप काम करते हैं? –

+0

ठीक है, जैसे * मुझे * नौकरी है। :) – MusiGenesis

+0

+1 ब्रावो

2

@MusiGenesis,

बस नोट करने के लिए मैं एक छवि संपादक मैं लिख रहा है के लिए इस विधि का इस्तेमाल किया है कि चाहता था।यह अच्छी तरह से काम करता है, लेकिन कभी कभी इस विधि इस लाइन पर एक AccessViolationException से चलाता है:

byte B = row[columnOffset]; 

मुझे एहसास हुआ कि ऐसा इसलिए है क्योंकि वहाँ bitdepth का कोई मानकीकरण था, इसलिए यदि एक छवि था 32 बिट रंग मैं इस त्रुटि हो रही थी।

BitmapData data = NewBitmap.LockBits(new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, NewBitmap.PixelFormat); 

लिए:

BitmapData data = NewBitmap.LockBits(new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); 

आशा इस में मदद करता है के रूप में यह मेरी समस्या का उन्मूलन है लगता है तो मैं इस लाइन बदल दिया है।

पोस्ट के लिए धन्यवाद।

जिब

+1

इसके बजाय आप' PixelFormat.Format32bppArgb' का उपयोग करना चाहेंगे, क्योंकि यह डिफ़ॉल्ट .NET बिटमैप प्रारूप है। – MusiGenesis

-1

मैं थोड़ा देर हो रही है, लेकिन जैसा कि इन तरह के परिवर्तनों के लिए अनुकूलित किया जाएगा और पिक्सल खुद के जोड़ तोड़ की तुलना में बहुत आसान है एक रंग मैट्रिक्स कार्यान्वयन का उपयोग करें: http://www.geekpedia.com/tutorial202_Using-the-ColorMatrix-in-Csharp.html

+1

यह वही गलती है जो बॉब ने मेरे प्रश्न में लिंक किए गए आलेख में किया है: रंग मैट्रिस विपरीत परिवर्तनों के लिए उपयुक्त नहीं हैं। ऐसा इसलिए है क्योंकि परिवर्तन काले भूरे रंग के, मध्यम भूरे रंग के सापेक्ष बने होते हैं। –

+0

बस इसे ठीक करने के लिए, 'नई फ्लोट [] {0.1 एफ, 0, 0, 0, 0}, नई फ्लोट [] {0, 0.1 एफ, 0, 0, 0}, नई फ्लोट [] {0 , 0, 0.1 एफ, 0, 0}, नई फ्लोट [] {0, 0, 0, 1, 0}, नई फ्लोट [] {0.8 एफ, 0.8 एफ, 0.8 एफ, 0, 1} ' करता है उपर्युक्त उदाहरण में नौकरी। पांचवीं पंक्ति एक ऑफ़सेट जोड़ती है जिसे समायोजित किया जा सकता है। यह (0.8) एक "उच्च कुंजी" प्रभाव देते हैं। 0.2 बहुत कम विपरीत है। – nick66

संबंधित मुद्दे