image Matlab में केवल काले रंग को सफेद में परिवर्तित करने के लिए




image-processing colors (4)

मैं इस धागे को काले रंग में सफेद और सफेद करने के लिए काला करने के लिए एक साथ परिवर्तित करने के बारे में जानता हूं। मैं केवल काला करने के लिए सफेद परिवर्तित करना चाहते हैं मुझे यह सब करने के बारे में पता है जो मैं पूछ रहा हूं लेकिन मुझे नहीं पता कि गलत क्या होता है

चित्र

कोड

rgbImage = imread('ecg.png');
grayImage = rgb2gray(rgbImage); % for non-indexed images
level = graythresh(grayImage); % threshold for converting image to binary, 
binaryImage = im2bw(grayImage, level); 
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Make the black parts pure red.
redChannel(~binaryImage) = 255;
greenChannel(~binaryImage) = 0;
blueChannel(~binaryImage) = 0;
% Now recombine to form the output image.
rgbImageOut = cat(3, redChannel, greenChannel, blueChannel);
imshow(rgbImageOut);

जो देता है

जहां लाल रंग चैनल में कुछ गलत लगता है ब्लैक रंग आरजीबी में बस (0,0,0) है, इसलिए इसका हटाने का मतलब प्रत्येक (0,0,0) पिक्सेल को सफेद (255,255,255) में बदलना है। इस विचार को साथ करना

redChannel(~binaryImage) = 255;
greenChannel(~binaryImage) = 255;
blueChannel(~binaryImage) = 255;

देता है

इसलिए मुझे माटलब में कुछ गलतफहमी होनी चाहिए नीले रंग में कोई भी काला नहीं होना चाहिए। तो यह आखिरी छवि अजीब है

आप केवल काले रंग को सफेद रंग कैसे बदल सकते हैं? मैं ईसीजी के नीले रंग को रखना चाहता हूं।


समस्या क्या है?

आप छवि के सभी काले भागों का पता लगाने के लिए चाहते हैं, लेकिन वे वास्तव में काले नहीं हैं

उदाहरण:

आपका विचार (या आपका कोड):

आप पहली बार छवि को बिनरराइज़ करते हैं, पिक्सल का चयन नहीं कर रहे हैं, जो पिक्सेल के खिलाफ हैं संक्षेप में, आप करते हैं: if pixel>level; pixel is something if pixel>level; pixel is something

इसलिए आपके पास यहां एक छोटी सी गलत धारणा है! जब आप लिखते हैं

% Make the black parts pure red.

इसे पढ़ना चाहिए

% Make every pixel that is something (not background) pure red.

इसलिए, जब आप करते हैं

redChannel(~binaryImage) = 255;
greenChannel(~binaryImage) = 255;
blueChannel(~binaryImage) = 255;

तुम कर रहे हो

% Make every pixel that is something (not background) white 
% (or what it is the same in this case, delete them).

इसलिए आपको जो चाहिए वह पूरी तरह से सफेद छवि है। छवि पूरी तरह से सफ़ेद नहीं है क्योंकि कुछ पिक्सेल हैं, जो कि आपकी छवि के करीब 0.6 के level के मूल्य के अनुसार "कुछ नहीं, पृष्ठभूमि का हिस्सा" के रूप में लेबल किया गया था।

एक समाधान जिसके बारे में कोई विचार कर सकता है वह मैन्युअल रूप से स्तर 0.05 या उसके समान सेट कर रहा है, इसलिए केवल काले पिक्सेल को ग्रेरी में बाइनरी थ्रेल्डिंग में चुना जाएगा। लेकिन यह 100% काम नहीं करेगा, जैसा कि आप देख सकते हैं, संख्याओं में कुछ बहुत "ना-काले" मूल्य हैं

मैं इस समस्या को हल करने की कोशिश कैसे करूंगा:

मैं उस रंग को ढूँढ़ने की कोशिश करता हूं जो आप चाहते हैं, छवि से उस रंग को निकालें, और उसके बाद आउटलेटर्स हटा दें।

एचएसवी का उपयोग करके नीला निकालें (मेरा मानना ​​है कि मैं आपको एचएसवी का उपयोग करने के लिए कहीं और उत्तर देता हूं)

rgbImage = imread('ecg.png');
hsvImage=rgb2hsv(rgbImage);
I=rgbImage;
R=I(:,:,1);
G=I(:,:,2);
B=I(:,:,3);
th=0.1;
R((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
G((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
B((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
I2= cat(3, R, G, B);

imshow(I2)

एक बार यहाँ हम सबसे बड़ा ब्लू हिस्सा प्राप्त करना चाहते हैं, और वह हमारा संकेत होगा इसलिए सबसे अच्छा तरीका पहले नीले पिक्सेल को ले जाने वाली छवि को बिनोराइज़ करने लगता है

% Binarize image, getting all the pixels that are "blue"
bw=im2bw(rgb2gray(I2),0.9999);

और फिर bwlabel का उपयोग bwlabel , सभी स्वतंत्र पिक्सेल "द्वीपों" को लेबल करें।

% Label each "blob"
lbl=bwlabel(~bw);

सबसे दोहराया लेबल संकेत हो जाएगा इसलिए हम उस लेबल को खोजते हुए पृष्ठभूमि को अलग करके संकेत को अलग करते हैं।

% Find the blob with the highes amount of data. That  will be your signal.
r=histc(lbl(:),1:max(lbl(:)));
[~,idxmax]=max(r);
% Profit!
signal=rgbImage;
signal(repmat((lbl~=idxmax),[1 1 3]))=255;
background=rgbImage;
background(repmat((lbl==idxmax),[1 1 3]))=255;

यहां संकेत, पृष्ठभूमि और अंतर के साथ एक भूखंड है (@rayryang के रूप में समान समीकरण का उपयोग किया गया है)


इसके लिए एक कोड है:

rgbImage = imread('ecg.png');

redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);

black = ~redChannel&~greenChannel&~blueChannel;

redChannel(black) = 255;
greenChannel(black) = 255;
blueChannel(black) = 255;

rgbImageOut = cat(3, redChannel, greenChannel, blueChannel);

imshow(rgbImageOut);

black पिक्सेल वाला क्षेत्र है ये पिक्सेल प्रत्येक रंग चैनल में सफ़ेद सेट हैं

आपके कोड में आप थ्रेसहोल्ड और एक ग्रेस्केल छवि का उपयोग करते हैं, इसलिए ज़ाहिर है कि आपके पास बहुत अधिक पिक्सल है जो सफेद resp पर सेट है लाल रंग। इस कोड में केवल पिक्सेल जिसमें पूर्णतः कोई लाल, हरा और नीला सफेद नहीं है।

निम्न कोड प्रत्येक रंग चैनल के लिए थ्रेशोल्ड के समान होता है:

rgbImage = imread('ecg.png');

redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);

black = (redChannel<150)&(greenChannel<150)&(blueChannel<150);

redChannel(black) = 255;
greenChannel(black) = 255;
blueChannel(black) = 255;

rgbImageOut = cat(3, redChannel, greenChannel, blueChannel);

imshow(rgbImageOut);

नीले सिग्नल निकालने के लिए @ रयरींग के समाधान पर यहां एक भिन्नता है:

%// retrieve picture
imgRGB = imread('http://i.stack.imgur.com/cFOSp.png');

%// detect axis lines and labels
imgHSV = rgb2hsv(imgRGB);
BW = (imgHSV(:,:,3) < 1);
BW = imclose(imclose(BW, strel('line',40,0)), strel('line',10,90));

%// clear those masked pixels by setting them to background white color
imgRGB2 = imgRGB;
imgRGB2(repmat(BW,[1 1 3])) = 255;

%// show extracted signal
imshow(imgRGB2)

बेहतर दृश्य प्राप्त करने के लिए, यहां मूल छवि के शीर्ष पर imoverlay का पता लगाया गया मुखौटा है (मैं फ़ाइल एक्सचेंज से imoverlay फ़ंक्शन का उपयोग कर रहा हूं):

figure
imshow(imoverlay(imgRGB, BW, uint8([255,0,0])))


अगर मैं आपको ठीक से समझता हूं, तो आप पाठ और कुल्हाड़ियों को हटाते हुए नीले ईसीजी प्लॉट को निकालना चाहते हैं। ऐसा करने का सबसे अच्छा तरीका छवि के एचएसवी रंगीन स्थान की जांच करना होगा। एचएसवी कलर स्पेस विवेकी रंगों के लिए महान है जैसे मनुष्य क्या करता है हम स्पष्ट रूप से देख सकते हैं कि छवि में दो भिन्न रंग हैं

हम rgb2hsv एचएसवी का उपयोग करके छवि को एचएसवी में बदल सकते हैं और हम अलग-अलग घटकों की जांच कर सकते हैं। रंग घटक पिक्सेल के प्रमुख रंग का प्रतिनिधित्व करता है, संतृप्ति पवित्रता को दर्शाती है या पिक्सेल में कितना सफेद प्रकाश है और मूल्य पिक्सेल की तीव्रता या ताकत को दर्शाता है।

प्रत्येक चैनल को देखने का प्रयास करें:

im = imread('http://i.stack.imgur.com/cFOSp.png'); %// Read in your image
hsv = rgb2hsv(im);
figure;
subplot(1,3,1); imshow(hsv(:,:,1)); title('Hue');
subplot(1,3,2); imshow(hsv(:,:,2)); title('Saturation');
subplot(1,3,3); imshow(hsv(:,:,3)); title('Value');

हम्म ... अच्छी तरह से रंग और संतृप्ति हमें बिल्कुल भी मदद नहीं करते हैं यह हमें प्रमुख रंग बता रहा है और संतृप्ति समान हैं ... लेकिन जो उन्हें अलग सेट करती है वह मूल्य है । यदि आप दाईं ओर छवि को देख लेते हैं, तो हम उन्हें रंग की ताकत से अलग बता सकते हैं। तो यह बता रहा है कि "ब्लैक" पिक्सेल वास्तव में नीले हैं लेकिन इसके साथ लगभग कोई ताकत नहीं है

हम वास्तव में इसका उपयोग हमारे लाभ में कर सकते हैं किसी भी पिक्सेल, जिसका मूल्य एक निश्चित मूल्य से अधिक है, वे मूल्य हैं जिन्हें हम रखना चाहते हैं।

एक थ्रेशोल्ड सेट करने का प्रयास करें ... 0.75 जैसा कुछ एचएसवी मूल्यों की MATLAB की गतिशील रेंज [0-1] , इसलिए:

mask = hsv(:,:,3) > 0.75;

जब हम मान घटक को थ्रेशोल्ड करते हैं, तो हम यही प्राप्त करते हैं:

स्पष्ट रूप से क्वानाइजेशन शोर का एक सा है ... विशेषकर कुल्हाड़ियों और फ़ॉन्ट के आसपास मैं आगे क्या करने जा रहा हूँ, एक आकारिकी कटाव करता है, ताकि मैं संख्याओं और कुल्हाड़ियों के चारों ओर के परिमाणीकरण शोर को समाप्त कर सकूं। मैं यह मुखौटा थोड़ा बड़ा करने के लिए सुनिश्चित करने के लिए जा रहा हूँ कि मैं इस शोर को हटा दें। इमेज प्रोसेसिंग टूलबॉक्स का उपयोग करना:

se = strel('square', 5);
mask_erode = imerode(mask, se);

हमें यह मिलता है:

अच्छा, तो मैं अब क्या करने जा रहा हूं, आपकी मूल छवि की प्रतिलिपि बनाएं, फिर किसी भी पिक्सेल को अंतिम छवि में सफेद पर मुखौटा (ऊपर) से निकाला गया। अन्य सभी पिक्सल को बरकरार रहना चाहिए। इस तरह, हम आपकी छवि में देखे गए किसी पाठ और कुल्हाड़ियों को हटा सकते हैं:

im_final = im;
mask_final = repmat(mask_erode, [1 1 3]);
im_final(~mask_final) = 255;

मुझे मुखौटा को तीसरा आयाम में दोहराने की आवश्यकता है क्योंकि यह एक रंग छवि है और मुझे प्रत्येक चैनल को एक ही स्थान में 255 पर एक साथ सेट करना होगा।

जब मैं ऐसा करता हूं, तो यही मुझे मिलता है:

अब आप देखेंगे कि ग्राफ़ में अंतराल है ... जो शराब के कारण शराब के कारण होने की उम्मीद है। हम इस छवि को ग्रेस्केल में बदलने और छवि थ्रेसहोल्ड करने के लिए कुछ और कर सकते हैं, फिर किनारों को एक आकृति विज्ञान फैलाव से जोड़कर भरना। यह सुरक्षित है क्योंकि हमने पहले से ही अक्ष और पाठ को हटा दिया है फिर हम इसे अंतिम चित्र में प्राप्त करने के लिए मूल छवि में सूचक को मुखौटा के रूप में उपयोग कर सकते हैं।

कुछ इस तरह:

im2 = rgb2gray(im_final);
thresh = im2 < 200;
se = strel('line', 10, 90);
im_dilate = imdilate(thresh, se);
mask2 = repmat(im_dilate, [1 1 3]);
im_final_final = 255*ones(size(im), class(im));
im_final_final(mask2) = im(mask2);

मैं पिछली छवि को थ्रेसहोल्ड करता हूं जिसको मैं पाठ और अक्षों के बिना मिला, जब मैं इसे ग्रेस्केल में परिवर्तित करता हूं, और फिर मैं एक रेखा संरचना तत्व के साथ फैलाव करता हूं जो क्रमशः डिस्कनेक्ट की गई उन पंक्तियों को जोड़ने के लिए 90 डिग्री है। इस थ्रेसहोल्ड छवि में वे पिक्सेल शामिल होंगे, जिन्हें हमें आखिरकार मूल छवि से नमूना बनाने की आवश्यकता होगी ताकि हम हमें जरूरत के ग्राफ डेटा प्राप्त कर सकें।

मैं फिर इस मुखौटा को ले लीजिए, इसे दोहराना, एक पूरी तरह से सफेद छवि बनाना और फिर मूल छवि से नमूना बनाना और वे स्थानों को जो हम मूल छवि से सफेद छवि में चाहते हैं, जगह दें।

यह हमारी अंतिम छवि है:

बहुत अच्छा! मुझे उस सभी इमेज प्रोसेसिंग के लिए करना था क्योंकि आपकी छवि मूल रूप से शुरू करने के लिए क्वानाइजेशन शोर है, इसलिए यह ग्राफ़ को पूरी तरह से प्राप्त करने में थोड़ा मुश्किल होगा। एंडर बिगुरी ने अपने जवाब में रंग की मात्रा का शोर के बारे में अधिक विस्तार से समझाया ताकि निश्चित रूप से अधिक विवरण के लिए उसकी पोस्ट देखें।

हालांकि, एक गुणात्मक उपाय के रूप में, हम इस छवि को मूल छवि से घटा सकते हैं और देखें कि शेष क्या है:

imshow(rgb2gray(abs(double(im) - double(im_final_final))));

हमें मिला:

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

सौभाग्य!





rgb