ম্যাট্রিক্স গুণ (ম্যাট্রিক্স ফর্ম) হিসাবে কোনও কনভোলিউশন কীভাবে প্রকাশ করা যায়?


11

আমি জানি এই প্রশ্নটি প্রোগ্রামিংয়ের সাথে খুব প্রাসঙ্গিক নাও হতে পারে, তবে আমি যদি চিত্র প্রক্রিয়াকরণের পিছনে তত্ত্বটি বুঝতে না পারি তবে আমি কখনই অনুশীলনে কিছু বাস্তবায়ন করতে সক্ষম হব না।

যদি আমার কাছে এটি ঠিক হয়ে যায় যে গাউসিয়ান ফিল্টারগুলি শব্দ হ্রাসের জন্য একটি চিত্রের সাথে মীমাংসিত হয় কারণ তারা একটি পিক্সেলের আশেপাশের গড় ওজনের গড় গণনা করে এবং প্রান্ত সনাক্তকরণে এগুলি খুব দরকারী, যেহেতু আপনি একটি ঝাপসা প্রয়োগ করতে পারেন এবং একই সাথে চিত্রটি অর্জন করতে পারেন কেবল কোনও গাউসিয়ান ফাংশনের ডেরাইভেটিভের সাথে সংশ্লেষ করা।

তবে যে কেউ আমাকে ব্যাখ্যা করতে পারে, বা তাদের কীভাবে গণনা করা যায় সে সম্পর্কে আমাকে কিছু উল্লেখ দিতে পারে?

উদাহরণস্বরূপ ক্যানির এজ ডিটেক্টর 5x5 গাউসিয়ান ফিল্টার সম্পর্কে কথা বলে তবে তারা কীভাবে এই বিশেষ নম্বর পেয়েছিল? এবং কীভাবে তারা একটি অবিচ্ছিন্ন সমঝোতা থেকে ম্যাট্রিক্সের গুণায় চলে গেল?



আমি ইমেজ কনভলিউশনের জন্য একটি ম্যাট্রিক্স তৈরির জন্য পূর্ণ কোড সহ একটি উত্তর যুক্ত করেছি ।
রয়ী

উত্তর:


3

এই অপারেশনটি কাজ করার জন্য, আপনাকে কল্পনা করতে হবে যে আপনার চিত্রটি ভেক্টর হিসাবে পুনরায় আকার দিয়েছে। তারপরে, এই ভেক্টরটি অস্পষ্ট চিত্রটি পাওয়ার জন্য কনভ্যুশন ম্যাট্রিক্স দ্বারা বাম দিকে গুন করা হয়েছে। নোট করুন যে ফলাফলটি একটি ভেক্টরও একই আকারের ইনপুট, অর্থাৎ একই আকারের একটি চিত্র image

কনভ্যুলেশন ম্যাট্রিক্সের প্রতিটি সারি ইনপুট চিত্রের এক পিক্সেলের সাথে মিলে যায়। এতে বিবেচিত পিক্সেলের অস্পষ্ট অংশের প্রতিচ্ছবিতে চিত্রের অন্যান্য সমস্ত পিক্সেলের অবদানের ওজন রয়েছে।

আসুন একটি উদাহরণ নেওয়া যাক: আকারের বক্স ব্লার 3×3 আকারের একটি ছবিতে পিক্সেল 6×6পিক্সেল। পুনরায় আকারযুক্ত চিত্রটি 36 টি নির্বাচনের কলাম, এবং অস্পষ্ট ম্যাট্রিক্সের আকার রয়েছে36×36

  • আসুন এই ম্যাট্রিক্সটি সর্বত্র 0 থেকে শুরু করুন।
  • এখন, স্থানাঙ্কের পিক্সেল বিবেচনা করুন (আমি,)ইনপুট চিত্রটিতে (সরলতার জন্য এর সীমানায় নয়)। এর অস্পষ্ট অংশটি ওজনের প্রয়োগের মাধ্যমে পাওয়া যায়1/9 নিজের এবং তার প্রতিবেশীদের প্রত্যেককে অবস্থানের জন্য (আমি-1,-1);(আমি-1,),(আমি-1,+ +1),...,(আমি+ +1,+ +1)
  • কলামে ভেক্টর, পিক্সেল (আমি,) অবস্থান আছে 6*আমি+ +(গ্রন্থাগার ক্রম অনুমান করে)। আমরা ওজন রিপোর্ট1/9 মধ্যে (6আমি+ +)অস্পষ্ট ম্যাট্রিক্সের -পথ লাইন।
  • অন্যান্য সমস্ত পিক্সেল দিয়ে একই করুন।

এই ব্লগ পোস্টে (আমার ব্যক্তিগত ব্লগ থেকে ) একটি নিবিড়ভাবে সম্পর্কিত প্রক্রিয়াটির একটি দৃশ্যের চিত্র (কনভলিউশন + বিয়োগফল) পাওয়া যাবে ।


একটি লিঙ্ক মারা গেছে।
গৌতেহ

2

চিত্রসমূহ বা কনভলিউশন নেটওয়ার্কগুলিতে অ্যাপ্লিকেশনগুলির জন্য, আধুনিক জিপিইউগুলিতে ম্যাট্রিক্স মাল্টিপ্লায়ারগুলি আরও দক্ষতার সাথে ব্যবহার করতে, ইনপুটগুলি সাধারণত একটি অ্যাক্টিভেশন ম্যাট্রিক্সের কলামগুলিতে পুনরায় আকার দেওয়া হয় যা একসাথে একাধিক ফিল্টার / কার্নেল দিয়ে গুণ করা যায়।

পরীক্ষা করে দেখুন এই লিঙ্কে স্ট্যানফোর্ড এর CS231n থেকে এবং বিস্তারিত জানার জন্য "ম্যাট্রিক্স গুণ হিসাবে বাস্তবায়ন" এ অধ্যায় নিচে স্ক্রোল করুন।

প্রক্রিয়াটি সমস্ত স্থানীয় প্যাচগুলি ইনপুট চিত্র বা অ্যাক্টিভেশন ম্যাপে নিয়ে যায়, কার্নেলের সাথে গুণিত হবে এবং সাধারণভাবে ইম 2col নামে পরিচিত একটি অপারেশনের মাধ্যমে এগুলি একটি নতুন ম্যাট্রিক্স এক্সের কলামে প্রসারিত করে কাজ করে। কার্নেলগুলি ওজন ম্যাট্রিক্স ডাব্লু এর সারিগুলি বসানোর জন্যও প্রসারিত করা হয় যাতে ম্যাট্রিক্স অপারেশন ডাব্লু * এক্স সঞ্চালনের সময়, ফলস্বরূপ ম্যাট্রিক্স ওয়াইয়ের সমাপ্তির সমস্ত ফলাফল থাকে। অবশেষে, ওয়াই ম্যাট্রিক্সকে অবশ্যই কলাম 2 নামক একটি অপারেশন দ্বারা কলামগুলি চিত্রগুলিতে ফিরে রূপান্তরিত করে পুনরায় আকার দিতে হবে।


1
এটি একটি খুব ভাল লিঙ্ক, ধন্যবাদ! তবে উত্তরের সাথে লিঙ্কটি থেকে গুরুত্বপূর্ণ সূত্রগুলি যুক্ত করা ভাল অনুশীলন, এইভাবে লিঙ্কটি বিরতি হলেও উত্তরটি বৈধ valid আপনার উত্তরটি গ্রহণ করার জন্য দয়া করে এডিটিং বিবেচনা করুন!
মাত্তেও

1

টাইম ডোমেনে কনভলিউশন ফ্রিকোয়েন্সি ডোমেনে ম্যাট্রিক্সের গুণ এবং এর বিপরীতে সমান।

ফিল্টারিং সময় ডোমেনে সমঝোতার সমতুল্য এবং তাই ফ্রিকোয়েন্সি ডোমেনে ম্যাট্রিক্সের গুণফল lic

5x5 মানচিত্র বা মাস্ক হিসাবে, তারা ক্যানি / সোবল অপারেটরদের বিবেচনা থেকে আসে।


2
ফিল্টারিং হ'ল ফ্রিকোয়েন্সি ডোমেনের একটি রূপান্তর হিসাবে এই সত্যের সাথে আমি একমত নই। আমরা এখানে যে ধরণের ফিল্টারগুলির কথা বলছি তা হ'ল স্থানিক ডোমেনে সংশ্লেষ (এটি বলতে গেলে, ফ্রিকোয়েন্সি ডোমেনের ফিল্টার প্রতিক্রিয়া দ্বারা উপাদান-ভিত্তিক গুণ)।
পিচনেট

আমি যা লিখেছি তা সংশোধন করার জন্য ধন্যবাদ। আমি পরবর্তী সম্পাদনা করেছি। আমার ধারণা পোস্ট দেওয়ার আগে আমার উত্তরগুলি ডাবল-চেক করা উচিত। তবে আমার উত্তরটির বেশিরভাগ অংশ এখনও দাঁড়িয়ে আছে।
নরেশ

ফুরিয়ার রূপান্তর প্রকৃতপক্ষে গুণগুলি (এবং তদ্বিপরীত) মধ্যে রূপান্তরগুলি পরিণত করে। তবে এগুলি পিন্ট وار গুণক, যখন প্রশ্নটি ম্যাট্রিক্স-ভেক্টর গুণগুলি যা ইমেজগুলিকে পুনর্নির্মাণের মাধ্যমে প্রাপ্ত।
সানসাইসো

আমি উল্লেখ করেছি যে অপারেটরদের কীভাবে বিবেচনা করা যায় তা ক্যানি / সোবেল অপারেটরদের জন্য প্রাপ্ত 5x5 ম্যাট্রিকের কারণ।
নরেশ

1

আমি একটি ফাংশন লিখেছি যা এটি আমার স্ট্যাকওভারফ্লো Q2080835 গিটহাব সংগ্রহস্থলে (একবার দেখুন CreateImageConvMtx()) এ সমাধান করে sol
আসলে ফাংশন কোনো সংবর্তন আকৃতি আপনি চান সমর্থন করতে পারে না - 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

আমি ইমেজ ফিল্টারিংয়ের জন্য ম্যাট্রিক্স তৈরি করার জন্য একটি ফাংশনও তৈরি করেছি (ম্যাটল্যাবের অনুরূপ ধারণা 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

কোডটি ম্যাটল্যাবের বিপরীতে বৈধ করা হয়েছিল imfilter()

আমার স্ট্যাকওভারফ্লো Q2080835 গিটহাব রিপোজিটরিতে সম্পূর্ণ কোড উপলব্ধ ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.