मैट्रिक्स गुणन (मैट्रिक्स फॉर्म) के रूप में एक कन्वर्सेशन कैसे व्यक्त किया जा सकता है?


11

मुझे पता है कि यह सवाल प्रोग्रामिंग के लिए बहुत प्रासंगिक नहीं हो सकता है, लेकिन अगर मैं इमेज प्रोसेसिंग के पीछे के सिद्धांत को नहीं समझ पाऊंगा तो मैं कभी भी व्यवहार में कुछ लागू नहीं कर पाऊंगा।

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

लेकिन क्या कोई मुझे समझा सकता है, या मुझे कुछ संदर्भ दे सकता है कि उनकी गणना कैसे की जाती है?

उदाहरण के लिए कैनी का एज डिटेक्टर 5x5 गाऊसी फिल्टर के बारे में बात करता है, लेकिन उन विशेष नंबरों को कैसे प्राप्त किया? और वे लगातार कनविक्शन से एक मैट्रिक्स गुणा तक कैसे गए?



मैंने छवि रूपांतरण के लिए एक मैट्रिक्स बनाने के लिए पूर्ण कोड के साथ एक उत्तर जोड़ा
रॉय

जवाबों:


3

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

कन्वेंशन मैट्रिक्स की प्रत्येक पंक्ति इनपुट छवि में एक पिक्सेल से मेल खाती है। इसमें इमेज के अन्य सभी पिक्सल्स के योगदान का वजन माना गया है, जो कि पिक्सलेट के धुंधले समकक्ष के लिए है।

आइए एक उदाहरण लेते हैं: आकार पिक्सेल की छवि पर पिक्सेल का बॉक्स धब्बा । रेज़ैप्ड छवि 36 चुनावों का एक कॉलम है, जबकि ब्लर मैट्रिक्स का आकार ।3×36×636×36

  • आइए इस मैट्रिक्स को हर जगह 0 पर निष्क्रिय करें।
  • अब, इनपुट छवि में निर्देशांक के पिक्सेल पर विचार करें सादगी के लिए इसकी सीमा पर नहीं)। इसका धुंधला प्रतिरूप और उसके प्रत्येक पड़ोसी के पदों पर भार लागू करके प्राप्त किया जाता है ।(i,j)1/9(i1,j1);(i1,j),(i1,j+1),,(i+1,j+1)
  • कॉलम वेक्टर में, पिक्सेल की स्थिति (लेक्सिकोग्राफिक ऑर्डरिंग मानते हुए) है। हम वजन रिपोर्ट में कलंक मैट्रिक्स के मई के लाइन।(i,j)6i+j1/9(6i+j)
  • अन्य सभी पिक्सेल के साथ भी ऐसा ही करें।

इस ब्लॉग पोस्ट (मेरे व्यक्तिगत ब्लॉग से) पर एक निकट से संबंधित प्रक्रिया (दृढ़ संकल्प + घटाव) का दृश्य चित्रण पाया जा सकता है ।


एक लिंक मर चुका है।
गौते

2

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

की जाँच करें इस लिंक स्टैनफोर्ड CS231n से, और जानकारी के लिए "द मैट्रिक्स गुणन के रूप में कार्यान्वयन" पर अनुभाग तक स्क्रॉल करें।

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


1
यह एक बहुत अच्छा लिंक है, धन्यवाद! हालाँकि उत्तर में लिंक से महत्वपूर्ण अर्क जोड़ने के लिए यह अच्छा अभ्यास है, इस तरह से लिंक के टूटने पर भी उत्तर मान्य है। कृपया इसे स्वीकार करने के लिए अपने उत्तर को संपादित करने पर विचार करें!
Matteo

1

टाइम डोमेन में कन्वेंशन आवृत्ति डोमेन में मैट्रिक्स गुणन के बराबर है और इसके विपरीत।

फ़िल्टरिंग टाइम डोमेन में कनवल्शन के बराबर है और इसलिए आवृत्ति डोमेन में मैट्रिक्स गुणन है।

5x5 मानचित्र या मास्क के रूप में, वे कैनी / सोबेल ऑपरेटरों के विवेक से आते हैं।


2
मैं इस तथ्य से सहमत नहीं हूं कि फ़िल्टरिंग फ़्रीक्वेंसी डोमेन में एक कनविक्शन है। हम यहां जिस तरह के फिल्टर के बारे में बात कर रहे हैं, वह स्थानिक डोमेन में दिए गए संकल्प हैं (यह कहना है, आवृत्ति डोमेन में फ़िल्टर प्रतिक्रिया द्वारा तत्व-वार गुणन)।
पीचनेट्स

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

फूरियर रूपांतरण वास्तव में कई गुना (और इसके विपरीत) में संकल्पों को बदल देता है। हालांकि, वे पिंट वार गुणा हैं, जबकि सवाल मैट्रिक्स-वेक्टर गुणा के बारे में है जो छवियों को फिर से आकार देकर प्राप्त किया जाता है।
संस्सुवो

मैंने उल्लेख किया कि कैनी / सोबेल ऑपरेटरों के लिए प्राप्त 5x5 मैट्रिसेस का कारण ऑपरेटरों का विवेकहीन होना है।
नरेश

1

मैंने एक समारोह लिखा, जो मेरे StackOverflow Q2080835 GitHub Repository (एक नज़र में देखें CreateImageConvMtx()) में इसे हल करता है ।
असल में समारोह किसी भी घुमाव के आकार आप चाहें तो समर्थन कर सकते हैं - full, sameऔर valid

कोड निम्नानुसार है:

function [ mK ] = CreateImageConvMtx( mH, numRows, numCols, convShape )

CONVOLUTION_SHAPE_FULL  = 1;
CONVOLUTION_SHAPE_SAME  = 2;
CONVOLUTION_SHAPE_VALID = 3;

switch(convShape)
    case(CONVOLUTION_SHAPE_FULL)
        % Code for the 'full' case
        convShapeString = 'full';
    case(CONVOLUTION_SHAPE_SAME)
        % Code for the 'same' case
        convShapeString = 'same';
    case(CONVOLUTION_SHAPE_VALID)
        % Code for the 'valid' case
        convShapeString = 'valid';
end

mImpulse = zeros(numRows, numCols);

for ii = numel(mImpulse):-1:1
    mImpulse(ii)    = 1; %<! Create impulse image corresponding to i-th output matrix column
    mTmp            = sparse(conv2(mImpulse, mH, convShapeString)); %<! The impulse response
    cColumn{ii}     = mTmp(:);
    mImpulse(ii)    = 0;
end

mK = cell2mat(cColumn);


end

मैंने इमेज फिल्टरिंग के लिए एक मैट्रिक्स बनाने के लिए एक फ़ंक्शन भी बनाया (MATLAB के समान विचार imfilter()):

function [ mK ] = CreateImageFilterMtx( mH, numRows, numCols, operationMode, boundaryMode )
%UNTITLED6 Summary of this function goes here
%   Detailed explanation goes here

OPERATION_MODE_CONVOLUTION = 1;
OPERATION_MODE_CORRELATION = 2;

BOUNDARY_MODE_ZEROS         = 1;
BOUNDARY_MODE_SYMMETRIC     = 2;
BOUNDARY_MODE_REPLICATE     = 3;
BOUNDARY_MODE_CIRCULAR      = 4;

switch(operationMode)
    case(OPERATION_MODE_CONVOLUTION)
        mH = mH(end:-1:1, end:-1:1);
    case(OPERATION_MODE_CORRELATION)
        % mH = mH; %<! Default Code is correlation
end

switch(boundaryMode)
    case(BOUNDARY_MODE_ZEROS)
        mK = CreateConvMtxZeros(mH, numRows, numCols);
    case(BOUNDARY_MODE_SYMMETRIC)
        mK = CreateConvMtxSymmetric(mH, numRows, numCols);
    case(BOUNDARY_MODE_REPLICATE)
        mK = CreateConvMtxReplicate(mH, numRows, numCols);
    case(BOUNDARY_MODE_CIRCULAR)
        mK = CreateConvMtxCircular(mH, numRows, numCols);
end


end


function [ mK ] = CreateConvMtxZeros( mH, numRows, numCols )
%UNTITLED6 Summary of this function goes here
%   Detailed explanation goes here

numElementsImage    = numRows * numCols;
numRowsKernel       = size(mH, 1);
numColsKernel       = size(mH, 2);
numElementsKernel   = numRowsKernel * numColsKernel;

vRows = reshape(repmat(1:numElementsImage, numElementsKernel, 1), numElementsImage * numElementsKernel, 1);
vCols = zeros(numElementsImage * numElementsKernel, 1);
vVals = zeros(numElementsImage * numElementsKernel, 1);

kernelRadiusV = floor(numRowsKernel / 2);
kernelRadiusH = floor(numColsKernel / 2);

pxIdx       = 0;
elmntIdx    = 0;

for jj = 1:numCols
    for ii = 1:numRows
        pxIdx = pxIdx + 1;
        for ll = -kernelRadiusH:kernelRadiusH
            for kk = -kernelRadiusV:kernelRadiusV
                elmntIdx = elmntIdx + 1;

                pxShift = (ll * numCols) + kk;

                if((ii + kk <= numRows) && (ii + kk >= 1) && (jj + ll <= numCols) && (jj + ll >= 1))
                    vCols(elmntIdx) = pxIdx + pxShift;
                    vVals(elmntIdx) = mH(kk + kernelRadiusV + 1, ll + kernelRadiusH + 1);
                else
                    vCols(elmntIdx) = pxIdx;
                    vVals(elmntIdx) = 0; % See the accumulation property of 'sparse()'.
                end
            end
        end
    end
end

mK = sparse(vRows, vCols, vVals, numElementsImage, numElementsImage);


end


function [ mK ] = CreateConvMtxSymmetric( mH, numRows, numCols )
%UNTITLED6 Summary of this function goes here
%   Detailed explanation goes here

numElementsImage    = numRows * numCols;
numRowsKernel       = size(mH, 1);
numColsKernel       = size(mH, 2);
numElementsKernel   = numRowsKernel * numColsKernel;

vRows = reshape(repmat(1:numElementsImage, numElementsKernel, 1), numElementsImage * numElementsKernel, 1);
vCols = zeros(numElementsImage * numElementsKernel, 1);
vVals = zeros(numElementsImage * numElementsKernel, 1);

kernelRadiusV = floor(numRowsKernel / 2);
kernelRadiusH = floor(numColsKernel / 2);

pxIdx       = 0;
elmntIdx    = 0;

for jj = 1:numCols
    for ii = 1:numRows
        pxIdx = pxIdx + 1;
        for ll = -kernelRadiusH:kernelRadiusH
            for kk = -kernelRadiusV:kernelRadiusV
                elmntIdx = elmntIdx + 1;

                pxShift = (ll * numCols) + kk;

                if(ii + kk > numRows)
                    pxShift = pxShift - (2 * (ii + kk - numRows) - 1);
                end

                if(ii + kk < 1)
                    pxShift = pxShift + (2 * (1 -(ii + kk)) - 1);
                end

                if(jj + ll > numCols)
                    pxShift = pxShift - ((2 * (jj + ll - numCols) - 1) * numCols);
                end

                if(jj + ll < 1)
                    pxShift = pxShift + ((2 * (1 - (jj + ll)) - 1) * numCols);
                end

                vCols(elmntIdx) = pxIdx + pxShift;
                vVals(elmntIdx) = mH(kk + kernelRadiusV + 1, ll + kernelRadiusH + 1);

            end
        end
    end
end

mK = sparse(vRows, vCols, vVals, numElementsImage, numElementsImage);


end


function [ mK ] = CreateConvMtxReplicate( mH, numRows, numCols )
%UNTITLED6 Summary of this function goes here
%   Detailed explanation goes here

numElementsImage    = numRows * numCols;
numRowsKernel       = size(mH, 1);
numColsKernel       = size(mH, 2);
numElementsKernel   = numRowsKernel * numColsKernel;

vRows = reshape(repmat(1:numElementsImage, numElementsKernel, 1), numElementsImage * numElementsKernel, 1);
vCols = zeros(numElementsImage * numElementsKernel, 1);
vVals = zeros(numElementsImage * numElementsKernel, 1);

kernelRadiusV = floor(numRowsKernel / 2);
kernelRadiusH = floor(numColsKernel / 2);

pxIdx       = 0;
elmntIdx    = 0;

for jj = 1:numCols
    for ii = 1:numRows
        pxIdx = pxIdx + 1;
        for ll = -kernelRadiusH:kernelRadiusH
            for kk = -kernelRadiusV:kernelRadiusV
                elmntIdx = elmntIdx + 1;

                pxShift = (ll * numCols) + kk;

                if(ii + kk > numRows)
                    pxShift = pxShift - (ii + kk - numRows);
                end

                if(ii + kk < 1)
                    pxShift = pxShift + (1 -(ii + kk));
                end

                if(jj + ll > numCols)
                    pxShift = pxShift - ((jj + ll - numCols) * numCols);
                end

                if(jj + ll < 1)
                    pxShift = pxShift + ((1 - (jj + ll)) * numCols);
                end

                vCols(elmntIdx) = pxIdx + pxShift;
                vVals(elmntIdx) = mH(kk + kernelRadiusV + 1, ll + kernelRadiusH + 1);

            end
        end
    end
end

mK = sparse(vRows, vCols, vVals, numElementsImage, numElementsImage);


end


function [ mK ] = CreateConvMtxCircular( mH, numRows, numCols )
%UNTITLED6 Summary of this function goes here
%   Detailed explanation goes here

numElementsImage    = numRows * numCols;
numRowsKernel       = size(mH, 1);
numColsKernel       = size(mH, 2);
numElementsKernel   = numRowsKernel * numColsKernel;

vRows = reshape(repmat(1:numElementsImage, numElementsKernel, 1), numElementsImage * numElementsKernel, 1);
vCols = zeros(numElementsImage * numElementsKernel, 1);
vVals = zeros(numElementsImage * numElementsKernel, 1);

kernelRadiusV = floor(numRowsKernel / 2);
kernelRadiusH = floor(numColsKernel / 2);

pxIdx       = 0;
elmntIdx    = 0;

for jj = 1:numCols
    for ii = 1:numRows
        pxIdx = pxIdx + 1;
        for ll = -kernelRadiusH:kernelRadiusH
            for kk = -kernelRadiusV:kernelRadiusV
                elmntIdx = elmntIdx + 1;

                pxShift = (ll * numCols) + kk;

                if(ii + kk > numRows)
                    pxShift = pxShift - numRows;
                end

                if(ii + kk < 1)
                    pxShift = pxShift + numRows;
                end

                if(jj + ll > numCols)
                    pxShift = pxShift - (numCols * numCols);
                end

                if(jj + ll < 1)
                    pxShift = pxShift + (numCols * numCols);
                end

                vCols(elmntIdx) = pxIdx + pxShift;
                vVals(elmntIdx) = mH(kk + kernelRadiusV + 1, ll + kernelRadiusH + 1);

            end
        end
    end
end

mK = sparse(vRows, vCols, vVals, numElementsImage, numElementsImage);


end

MATLAB के खिलाफ कोड को मान्य किया गया था imfilter()

पूर्ण कोड मेरे StackOverflow Q2080835 GitHub रिपॉजिटरी में उपलब्ध है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.