ইমেজ প্রসেসিং OpenCV

Imeja Prasesim Opencv



আমরা এই নিবন্ধে ইমেজ-প্রসেসিং পদ্ধতিগুলি অধ্যয়ন করতে যাচ্ছি। আমরা কম্পিউটার ভিশন এবং মেশিন লার্নিং এর কিছু মৌলিক কিন্তু সমালোচনামূলক বিষয় পরীক্ষা করব। এই মৌলিক চিত্র প্রক্রিয়াকরণ কৌশলগুলি ডেটাসেটের মতো জটিল সমস্যার সমাধান করতে পারে। ফলস্বরূপ, চিত্র প্রক্রিয়াকরণে ছয়টি মৌলিক পদক্ষেপ রয়েছে, যা নীচে তালিকাভুক্ত করা হয়েছে:
  1. ছবি অনুবাদ
  2. ইমেজ ঘূর্ণন
  3. চিত্র পাটিগণিত
  4. ইমেজ ফ্লিপিং
  5. ছবি ক্রপিং
  6. ইমেজ রিসাইজিং

এখন, আমরা উপরে উল্লিখিত সমস্ত ইমেজ প্রসেসিং বিষয়গুলি বিস্তারিতভাবে ব্যাখ্যা করব।

1. চিত্র অনুবাদ

ইমেজ ট্রান্সলেশন হল একটি ইমেজ প্রসেসিং পদ্ধতি যা আমাদেরকে x এবং y-অক্ষ বরাবর ইমেজ সরাতে সাহায্য করে। আমরা ইমেজটিকে উপরে, নিচে, ডানে, বামে বা যেকোনো কম্বিনেশনে নিয়ে যেতে পারি।







আমরা ট্রান্সলেশন ম্যাট্রিক্সকে M প্রতীক দিয়ে সংজ্ঞায়িত করতে পারি এবং আমরা এটিকে গাণিতিক আকারে উপস্থাপন করতে পারি, যেমনটি নীচে দেখানো হয়েছে:





আমরা এই প্রোগ্রামের মাধ্যমে অনুবাদ চিত্রের ধারণা বুঝতে পারি।





পাইথন কোড: আমরা নিম্নলিখিত প্রোগ্রামের নাম হিসাবে রাখব translate.py .

#টি প্রয়োজনীয় প্যাকেজ আমদানি করুন

আমদানি নম্র হিসাবে যেমন

আমদানি argparse

আমদানি imutil

আমদানি cv2

# আমরা আর্গুমেন্ট পার্সার বাস্তবায়ন করি

ap_obj = argparse আর্গুমেন্ট পার্সার ( )

ap_obj add_argument ( '-কে' , '--ছবি' , প্রয়োজনীয় = সত্য ,

সাহায্য = 'ছবি ফাইলের অবস্থান' )

args = যার ( ap_obj পার্স_আর্গস ( ) )

# ছবিটি লোড করুন এবং স্ক্রিনে দেখান

ইমেজ = cv2. imread ( args [ 'ছবি' ] )

cv2. imshow ( 'মূল_ছবি' , ইমেজ )

# চিত্রটির অনুবাদ একটি NumPy ম্যাট্রিক্স যা নীচে দেওয়া হয়েছে:

# [[1, 0, shiftX], [0, 1, shiftY]]

# আমরা উপরের NumPy ম্যাট্রিক্স ব্যবহার করতে যাচ্ছি চিত্রগুলি বরাবর স্থানান্তর করতে

# x-অক্ষ এবং y-অক্ষের দিকনির্দেশ। এর জন্য, আমাদের কেবল পিক্সেলের মানগুলি পাস করতে হবে।

# এই প্রোগ্রামে, আমরা ছবিটি 30 পিক্সেল ডানদিকে নিয়ে যাব

# এবং নীচের দিকে 70 পিক্সেল।

অনুবাদ_ম্যাট = যেমন float32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

ছবি_অনুবাদ = cv2. warpAffine ( ইমেজ , অনুবাদ_ম্যাট ,

( ইমেজ আকৃতি [ 1 ] , ইমেজ আকৃতি [ 0 ] ) )

cv2. imshow ( 'চিত্র অনুবাদ ডাউন এবং ডান' , ছবি_অনুবাদ )

# এখন, আমরা উপরের NumPy ম্যাট্রিক্স ব্যবহার করতে যাচ্ছি ইমেজগুলিকে বরাবর স্থানান্তর করতে

# x-অক্ষ (বাম) এবং y-অক্ষ (উপরের) দিকনির্দেশ।

# এখানে, আমরা ছবিগুলিকে 50 পিক্সেল বাম দিকে সরাতে যাচ্ছি

# এবং 90 পিক্সেল উপরের দিকে।

অনুবাদ_ম্যাট = যেমন float32 ( [ [ 1 , 0 , - পঞ্চাশ ] , [ 0 , 1 , - 90 ] ] )

ছবি_অনুবাদ = cv2. warpAffine ( ইমেজ , অনুবাদ_ম্যাট ,

( ইমেজ আকৃতি [ 1 ] , ইমেজ আকৃতি [ 0 ] ) )

cv2. imshow ( 'ছবির অনুবাদ উপরে এবং বামে' , ছবি_অনুবাদ )

cv2. অপেক্ষা কী ( 0 )

লাইন 1 থেকে 5: আমরা এই প্রোগ্রামের জন্য প্রয়োজনীয় সমস্ত প্যাকেজ আমদানি করছি, যেমন OpenCV, argparser, এবং NumPy। দয়া করে মনে রাখবেন যে আরেকটি লাইব্রেরি আছে যা ইমুটিলস। এটি OpenCV এর প্যাকেজ নয়। এটি একটি লাইব্রেরি যা সহজেই একই চিত্র প্রক্রিয়াকরণ দেখাবে।



আমরা যখন OpenCV ইন্সটল করি তখন লাইব্রেরি imutils স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত হবে না। তাই imutils ইনস্টল করার জন্য, আমাদের নিম্নলিখিত পদ্ধতি ব্যবহার করতে হবে:

পিপ ইমুটিলস ইনস্টল করুন

লাইন 8 থেকে 15: আমরা আমাদের agrparser তৈরি করেছি এবং আমাদের চিত্র লোড করেছি।

লাইন 24 থেকে 25: এই প্রোগ্রাম অংশ যেখানে অনুবাদ ঘটে. অনুবাদ ম্যাট্রিক্স আমাদের বলে যে ছবিটি কত পিক্সেল উপরে বা নীচে বা বাম বা ডানে সরানো হবে। যেহেতু OpenCV-এর জন্য ম্যাট্রিক্স মান একটি ফ্লোটিং পয়েন্ট অ্যারেতে থাকা প্রয়োজন, অনুবাদ ম্যাট্রিক্স ফ্লোটিং পয়েন্ট অ্যারেতে মান নেয়।

অনুবাদ ম্যাট্রিক্সের প্রথম সারিটি এইরকম দেখাচ্ছে:

ম্যাট্রিক্সের এই সারিটি x-অক্ষের জন্য। টি এর মান এক্স ছবিটি বাম বা ডান দিকে স্থানান্তরিত হবে কিনা তা নির্ধারণ করবে। যদি আমরা একটি নেতিবাচক মান পাস করি, তাহলে এর অর্থ হল ছবিটি বাম দিকে স্থানান্তরিত হবে, এবং যদি মানটি ইতিবাচক হয়, তাহলে এর অর্থ হল ছবিটি ডানদিকে স্থানান্তরিত হবে।

আমরা এখন ম্যাট্রিক্সের দ্বিতীয় সারিটিকে নিম্নরূপ সংজ্ঞায়িত করব:

ম্যাট্রিক্সের এই সারিটি y-অক্ষের জন্য। টি এর মান Y ছবিটি উপরে বা ডাউনসাইডে স্থানান্তরিত হবে কিনা তা সিদ্ধান্ত নেবে। যদি আমরা একটি নেতিবাচক মান পাস করি, তাহলে এর অর্থ হল ছবিটি উল্টো দিকে স্থানান্তরিত হবে, এবং যদি মানটি ইতিবাচক হয়, তাহলে এর অর্থ হল ছবিটি ডাউনসাইডে স্থানান্তরিত হবে।

24 লাইনে পূর্ববর্তী প্রোগ্রামে, আমরা টি সংজ্ঞায়িত করেছি এক্স = 30 এবং টি Y = 70. তাই আমরা ছবিটিকে 30 পিক্সেল ডান দিকে এবং 70 পিক্সেল নিচের দিকে নিয়ে যাচ্ছি।

কিন্তু মূল চিত্র অনুবাদ প্রক্রিয়া 25 লাইনে সঞ্চালিত হয়, যেখানে আমরা অনুবাদ ম্যাট্রিক্স সংজ্ঞায়িত করি cv2.warpAffine . এই ফাংশনে, আমরা তিনটি প্যারামিটার পাস করছি: প্রথম প্যারামিটারটি চিত্র, দ্বিতীয় প্যারামিটারটি অনুবাদ ম্যাট্রিক্স এবং তৃতীয় প্যারামিটারটি চিত্রের মাত্রা।

লাইন 27: লাইন 27 আউটপুটে ফলাফল প্রদর্শন করবে।

এখন, আমরা বাম এবং ঊর্ধ্বগতির জন্য আরেকটি অনুবাদ ম্যাট্রিক্স বাস্তবায়ন করব। এর জন্য, আমাদের মানকে ঋণাত্মকভাবে সংজ্ঞায়িত করতে হবে।

লাইন 33 থেকে 34: 33 লাইনে পূর্ববর্তী প্রোগ্রামে, আমরা টি সংজ্ঞায়িত করেছি এক্স = -50 এবং টি Y = -90। তাই আমরা ছবিটি 50 পিক্সেল বাম দিকে এবং 90 পিক্সেল উপরের দিকে নিয়ে যাচ্ছি। কিন্তু মূল চিত্র অনুবাদ প্রক্রিয়াটি 34 লাইনে ঘটে, যেখানে আমরা অনুবাদ ম্যাট্রিক্সকে সংজ্ঞায়িত করি cv2.warpAffine .

লাইন 36 : লাইন 36 আউটপুটে দেখানো ফলাফল প্রদর্শন করবে।

আগের কোড রান করার জন্য নিচের মত করে ছবির পাথ দিতে হবে।

আউটপুট: python translate.py –image squirrel.jpg

এখন, আমরা ব্যবহার করে একই চিত্র অনুবাদ প্রোগ্রাম বাস্তবায়ন করব imutil লাইব্রেরি এই লাইব্রেরিটি ইমেজ প্রসেসিংয়ের জন্য ব্যবহার করা খুবই সহজ। এই লাইব্রেরিতে, আমাদের চিন্তা করতে হবে না cv2.warpAffine কারণ এই লাইব্রেরি এটির যত্ন নেবে। তাহলে আসুন imutils লাইব্রেরি ব্যবহার করে এই ইমেজ ট্রান্সলেশন প্রোগ্রামটি বাস্তবায়ন করি।

পাইথন কোড: আমরা নিম্নলিখিত প্রোগ্রামের নাম হিসাবে রাখব translate_imutils.py .

# প্রয়োজনীয় প্যাকেজ আমদানি করুন

আমদানি নম্র হিসাবে যেমন

আমদানি argparse

আমদানি imutil

আমদানি cv2

# এই ফাংশনটি ইমেজ অনুবাদ বাস্তবায়ন করে এবং

# কলিং ফাংশনে অনূদিত ছবি ফিরিয়ে দেয়।

ডিফ অনুবাদ করা ( ইমেজ , এক্স , Y ) :

অনুবাদ_ম্যাট্রিক্স = যেমন float32 ( [ [ 1 , 0 , এক্স ] , [ 0 , 1 , Y ] ] )

ছবি_অনুবাদ = cv2. warpAffine ( ইমেজ , অনুবাদ_ম্যাট্রিক্স ,

( ইমেজ আকৃতি [ 1 ] , ইমেজ আকৃতি [ 0 ] ) )

ফিরে ছবি_অনুবাদ

# আর্গুমেন্ট পার্সার তৈরি করুন এবং আর্গুমেন্ট পার্স করুন

ap = argparse আর্গুমেন্ট পার্সার ( )

ap add_argument ( '-আমি' , '--ছবি' , প্রয়োজনীয় = সত্য , সাহায্য = 'চিত্রের পথ' )

args = যার ( ap পার্স_আর্গস ( ) )

# ছবিটি লোড করুন এবং স্ক্রিনে প্রদর্শন করুন

ইমেজ = cv2. imread ( args [ 'ছবি' ] )

cv2. imshow ( 'মূল_ছবি' , ইমেজ )

ছবি_অনুবাদ = imutil অনুবাদ করা ( ইমেজ , 10 , 70 )

cv2. imshow ( 'ইমেজ অনুবাদ ডানদিকে এবং খারাপ দিকে' ,

ছবি_অনুবাদ )

cv2. অপেক্ষা কী ( 0 )

লাইন 9 থেকে 13: প্রোগ্রামের এই বিভাগটি যেখানে অনুবাদ হয়। ট্রান্সলেশন ম্যাট্রিক্স আমাদের জানায় যে ছবি কত পিক্সেল উপরে বা নিচে বা বাম বা ডানে সরানো হবে।

এই লাইনগুলি ইতিমধ্যে ব্যাখ্যা করা হয়েছে, কিন্তু এখন আমরা translate () নামে একটি ফাংশন তৈরি করতে যাচ্ছি এবং এতে তিনটি স্বতন্ত্র প্যারামিটার পাঠাব। ইমেজ নিজেই প্রথম প্যারামিটার হিসাবে কাজ করে। অনুবাদ ম্যাট্রিক্সের x, এবং y মান দ্বিতীয় এবং তৃতীয় প্যারামিটারের সাথে মিলে যায়।

বিঃদ্রঃ : প্রোগ্রামের ভিতরে এই অনুবাদ ফাংশনটি সংজ্ঞায়িত করার কোন প্রয়োজন নেই কারণ এটি ইতিমধ্যেই imutils লাইব্রেরি প্যাকেজে অন্তর্ভুক্ত রয়েছে। আমি সহজবোধ্য ব্যাখ্যার জন্য প্রোগ্রামের মধ্যে এটি ব্যবহার করেছি। আমরা এই ফাংশনটিকে সরাসরি imutils দিয়ে কল করতে পারি, যেমনটি 24 লাইনে দেখানো হয়েছে।

লাইন 24: পূর্ববর্তী প্রোগ্রামটি দেখাবে যে লাইন 24 এ, আমরা tx = 10 এবং ty = 70 সংজ্ঞায়িত করি। তাই আমরা চিত্রটিকে 10 পিক্সেল ডান দিকে এবং 70 পিক্সেল নিচের দিকে নিয়ে যাচ্ছি।

এই প্রোগ্রামে, আমরা কোন cv2.warpAffine ফাংশন সম্পর্কে চিন্তা করি না কারণ সেগুলি ইতিমধ্যেই imutils লাইব্রেরি প্যাকেজের ভিতরে রয়েছে।

পূর্ববর্তী কোডটি চালানোর জন্য, আমাদের নীচের মত চিত্রের পাথ দিতে হবে:

আউটপুট:

পাইথন ইমুটিলস। py --ছবি কাঠবিড়ালি। jpg

2. চিত্র ঘূর্ণন

আমরা পূর্ববর্তী পাঠে (অথবা যেকোনো সংমিশ্রণে) একটি চিত্রকে উপরে, নীচে, বাম এবং ডানে কীভাবে অনুবাদ করতে হয় (অর্থাৎ, স্থানান্তরিত) তা দেখেছি। এর পরে, আমরা ঘূর্ণন নিয়ে আলোচনা করব কারণ এটি চিত্র প্রক্রিয়াকরণের সাথে সম্পর্কিত।

একটি ছবি একটি কোণ, থিটা দ্বারা ঘোরানো হয়, যা ঘূর্ণন নামে পরিচিত। যে কোণ দ্বারা আমরা চিত্রটিকে ঘোরাতেছি তা থিটা দ্বারা উপস্থাপন করা হবে। উপরন্তু, আমি পরে ঘূর্ণন সুবিধার ফাংশন প্রদান করব যাতে ঘূর্ণায়মান চিত্রগুলি সহজতর হয়।

অনুবাদের অনুরূপ, এবং সম্ভবত আশ্চর্যজনক নয়, একটি কোণ দ্বারা ঘূর্ণন, থিটা নিম্নলিখিত বিন্যাসে একটি ম্যাট্রিক্স M তৈরি করে নির্ধারিত হয়:

এই ম্যাট্রিক্সটি একটি ভেক্টর থিটা ডিগ্রী (ঘড়ির কাঁটার বিপরীত দিকে) প্রদত্ত উৎপত্তি (x, y)-কার্টেসিয়ান সমতলের চারপাশে ঘোরাতে পারে। সাধারণত, এই দৃশ্যে, উত্সটি ছবির কেন্দ্র হবে, কিন্তু বাস্তবে, আমরা আমাদের ঘূর্ণন কেন্দ্র হিসাবে যে কোনও এলোমেলো (x, y) বিন্দুকে মনোনীত করতে পারি।

ঘূর্ণিত ছবি R তারপর আসল চিত্র থেকে তৈরি করা হয় I সরল ম্যাট্রিক্স গুণ ব্যবহার করে: R = IM

অন্যদিকে, OpenCV অতিরিক্তভাবে (1) একটি চিত্রকে স্কেল করার (অর্থাৎ আকার পরিবর্তন করার) ক্ষমতা প্রদান করে এবং (2) চারপাশে ঘূর্ণন চালানোর জন্য একটি নির্বিচারে ঘূর্ণন কেন্দ্র অফার করে।

আমাদের পরিবর্তিত ঘূর্ণন ম্যাট্রিক্স M নীচে দেখানো হয়েছে:

নামক একটি নতুন ফাইল ওপেন এবং জেনারেট করে শুরু করা যাক rotate.py :

# প্রয়োজনীয় প্যাকেজ আমদানি করা হচ্ছে

আমদানি নম্র হিসাবে যেমন

আমদানি argparse

আমদানি imutil

আমদানি cv2

# আর্গুমেন্টপার্সার অবজেক্ট তৈরি করা এবং আর্গুমেন্ট পার্স করা

apobj = argparse আর্গুমেন্ট পার্সার ( )

apobj add_argument ( '-কে' , '--ছবি' , প্রয়োজনীয় = সত্য , সাহায্য = 'চিত্র পথ' )

যুক্তি = যার ( apobj পার্স_আর্গস ( ) )

ইমেজ = cv2. imread ( যুক্তি [ 'ছবি' ] )

cv2. imshow ( 'মূল_ছবি' , ইমেজ )

# চিত্রের মাত্রা ব্যবহার করে ছবির কেন্দ্র গণনা করুন।

( উচ্চতা , প্রস্থ ) = ইমেজ আকৃতি [ : 2 ]

( centerX , কেন্দ্রওয়াই ) = ( প্রস্থ / 2 , উচ্চতা / 2 )

# এখন, cv2 ব্যবহার করে, আমরা চিত্রটিকে 55 ডিগ্রিতে ঘোরাব

# getRotationMatrix2D() ব্যবহার করে ঘূর্ণন ম্যাট্রিক্স নির্ধারণ করুন

ঘূর্ণন ম্যাট্রিক্স = cv2. GetRotationMatrix2D ( ( centerX , কেন্দ্রওয়াই ) , 55 , 1.0 )

ঘোরানো চিত্র = cv2. warpAffine ( ইমেজ , ঘূর্ণন ম্যাট্রিক্স , ( প্রস্থ , উচ্চতা ) )

cv2. imshow ( 'ছবিটিকে 55 ডিগ্রি ঘোরানো হয়েছে' , ঘোরানো চিত্র )

cv2. অপেক্ষা কী ( 0 )

# ছবিটি এখন -85 ডিগ্রি দ্বারা ঘোরানো হবে।

ঘূর্ণন ম্যাট্রিক্স = cv2. GetRotationMatrix2D ( ( centerX , কেন্দ্রওয়াই ) , - 85 , 1.0 )

ঘোরানো চিত্র = cv2. warpAffine ( ইমেজ , ঘূর্ণন ম্যাট্রিক্স , ( প্রস্থ , উচ্চতা ) )

cv2. imshow ( 'চিত্রটিকে -85 ডিগ্রী দ্বারা ঘোরানো হয়েছে' , ঘোরানো চিত্র )

cv2. অপেক্ষা কী ( 0 )

লাইন 1 থেকে 5: আমরা এই প্রোগ্রামের জন্য প্রয়োজনীয় সমস্ত প্যাকেজ আমদানি করছি, যেমন OpenCV, argparser, এবং NumPy। দয়া করে মনে রাখবেন যে আরেকটি লাইব্রেরি আছে যা ইমুটিলস। এটি OpenCV এর প্যাকেজ নয়। এটি একটি লাইব্রেরি যা একই চিত্র প্রক্রিয়াকরণ সহজে দেখানোর জন্য ব্যবহার করা হবে।

আমরা যখন OpenCV ইন্সটল করি তখন লাইব্রেরি imutils স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত হবে না। OpenCV imutils ইনস্টল করে। আমাদের নিম্নলিখিত পদ্ধতি ব্যবহার করতে হবে:

পিপ ইমুটিলস ইনস্টল করুন

লাইন 8 থেকে 14: আমরা আমাদের agrparser তৈরি করেছি এবং আমাদের চিত্র লোড করেছি। এই আর্গপার্সারে, আমরা শুধুমাত্র একটি ইমেজ আর্গুমেন্ট ব্যবহার করি, যা আমাদের ইমেজের পাথ বলে দেবে যা আমরা এই প্রোগ্রামে ঘূর্ণন প্রদর্শন করতে ব্যবহার করব।

একটি চিত্র ঘোরানোর সময়, আমাদের অবশ্যই ঘূর্ণনের পিভট পয়েন্টটি সংজ্ঞায়িত করতে হবে। বেশিরভাগ সময়, আপনি একটি চিত্রকে এর কেন্দ্রে ঘোরাতে চান, তবে OpenCV আপনাকে পরিবর্তে যেকোনো র্যান্ডম পয়েন্ট বেছে নিতে দেয়। আসুন কেবল চিত্রটিকে কেন্দ্রের চারপাশে ঘোরান।

লাইন 17 থেকে 18 চিত্রের প্রস্থ এবং উচ্চতা যথাক্রমে নিন এবং তারপর প্রতিটি মাত্রাকে দুই দ্বারা ভাগ করে ছবির কেন্দ্র স্থাপন করুন।

আমরা একটি চিত্রকে ঘোরানোর জন্য একটি ম্যাট্রিক্স তৈরি করি যেভাবে আমরা একটি চিত্রকে অনুবাদ করার জন্য একটি ম্যাট্রিক্সকে সংজ্ঞায়িত করেছি। আমরা শুধু কল করব cv2.getRotationMatrix2D NumPy ব্যবহার করে ম্যানুয়ালি ম্যাট্রিক্স তৈরি করার পরিবর্তে লাইন 22-এ ফাংশন (যা একটু কষ্টকর হতে পারে)।

দ্য cv2.getRotationMatrix2D ফাংশনের জন্য তিনটি পরামিতি প্রয়োজন। প্রথম ইনপুটটি পছন্দসই ঘূর্ণন কোণ (এই ক্ষেত্রে, চিত্রের কেন্দ্র)। তারপরে থিটা ব্যবহার করা হয় কতগুলি (ঘড়ির কাঁটার বিপরীতে) ডিগ্রীতে আমরা চিত্রটিকে ঘোরাব। এখানে, আমরা ছবিটি 45 ডিগ্রি ঘোরাব। চূড়ান্ত বিকল্পটি ছবির আকারের সাথে সম্পর্কিত।

আমরা এখনও কোনও চিত্রকে স্কেল করার বিষয়ে আলোচনা করিনি তা নির্বিশেষে, আপনি এখানে 1.0 সহ একটি ফ্লোটিং-পয়েন্ট নম্বর প্রদান করতে পারেন যা নির্দেশ করে যে ছবিটি তার আসল অনুপাতে ব্যবহার করা উচিত। যাইহোক, আপনি যদি 2.0 এর মান টাইপ করেন, তাহলে ছবিটির আকার দ্বিগুণ হবে। 0.5 এর একটি সংখ্যা ছবির আকার কমিয়ে দেয়।

লাইন 22 থেকে 23: থেকে আমাদের ঘূর্ণন ম্যাট্রিক্স M প্রাপ্তির পর cv2.getRotationMatrix2D ফাংশন, আমরা ব্যবহার করে আমাদের ইমেজ ঘোরান cv2.warpAffine 23 লাইনে কৌশল। ফাংশনের প্রথম ইনপুট হল সেই ইমেজ যা আমরা ঘোরাতে চাই। আমাদের আউটপুট চিত্রের প্রস্থ এবং উচ্চতা তারপরে সংজ্ঞায়িত করা হয়, আমাদের ঘূর্ণন ম্যাট্রিক্স M এর সাথে। লাইন 23-এ, চিত্রটি 55 ডিগ্রি দ্বারা ঘোরানো হয়।

আপনি লক্ষ্য করতে পারেন যে আমাদের চিত্রটি ঘোরানো হয়েছে।

লাইন 28 থেকে 30 দ্বিতীয় ঘূর্ণন গঠন. কোডের 22-23 লাইনগুলি অভিন্ন, এইবার আমরা 55-এর বিপরীতে -85 ডিগ্রী ঘোরে।

আমরা এই বিন্দু পর্যন্ত তার কেন্দ্রের চারপাশে একটি চিত্র ঘোরেছি। যদি আমরা একটি এলোমেলো বিন্দুর চারপাশে চিত্রটিকে ঘোরাতে চাই?

নামক একটি নতুন ফাইল ওপেন এবং জেনারেট করে শুরু করা যাক rotate.py:

# প্রয়োজনীয় প্যাকেজ আমদানি করা হচ্ছে

আমদানি নম্র হিসাবে যেমন

আমদানি argparse

আমদানি imutil

আমদানি cv2

# আর্গুমেন্টপার্সার অবজেক্ট তৈরি করা এবং আর্গুমেন্ট পার্স করা

ap_obj = argparse আর্গুমেন্ট পার্সার ( )

ap_obj add_argument ( '-কে' , '--ছবি' , প্রয়োজনীয় = সত্য , সাহায্য = 'চিত্র পথ' )

যুক্তি = যার ( ap_obj পার্স_আর্গস ( ) )

# ছবিটি লোড করুন এবং স্ক্রিনে প্রদর্শন করুন

ইমেজ = cv2. imread ( যুক্তি [ 'ছবি' ] )

cv2. imshow ( 'মূল_ছবি' , ইমেজ )

# চিত্রের মাত্রা ব্যবহার করে ছবির কেন্দ্র গণনা করুন।

( উচ্চতা , প্রস্থ ) = ইমেজ আকৃতি [ : 2 ]

( centerX , কেন্দ্রওয়াই ) = ( প্রস্থ / 2 , উচ্চতা / 2 )

# এখন, cv2 ব্যবহার করে, আমরা চিত্রটিকে 55 ডিগ্রিতে ঘোরাব

# getRotationMatrix2D() ব্যবহার করে ঘূর্ণন ম্যাট্রিক্স নির্ধারণ করুন

ঘূর্ণন ম্যাট্রিক্স = cv2. GetRotationMatrix2D ( ( centerX , কেন্দ্রওয়াই ) , 55 , 1.0 )

ঘোরানো চিত্র = cv2. warpAffine ( ইমেজ , ঘূর্ণন ম্যাট্রিক্স , ( প্রস্থ , উচ্চতা ) )

cv2. imshow ( 'ছবিটিকে 55 ডিগ্রি ঘোরানো হয়েছে' , ঘোরানো চিত্র )

cv2. অপেক্ষা কী ( 0 )

# ছবিটি এখন -85 ডিগ্রি দ্বারা ঘোরানো হবে।

ঘূর্ণন ম্যাট্রিক্স = cv2. GetRotationMatrix2D ( ( centerX , কেন্দ্রওয়াই ) , - 85 , 1.0 )

ঘোরানো চিত্র = cv2. warpAffine ( ইমেজ , ঘূর্ণন ম্যাট্রিক্স , ( প্রস্থ , উচ্চতা ) )

cv2. imshow ( 'চিত্রটিকে -85 ডিগ্রী দ্বারা ঘোরানো হয়েছে' , ঘোরানো চিত্র )

cv2. অপেক্ষা কী ( 0 )

# ছবির ঘূর্ণন কিছু নির্বিচারে বিন্দু থেকে, কেন্দ্র থেকে নয়

ঘূর্ণন ম্যাট্রিক্স = cv2. GetRotationMatrix2D ( ( centerX - 40 , কেন্দ্রওয়াই - 40 ) , 55 , 1.0 )

ঘোরানো চিত্র = cv2. warpAffine ( ইমেজ , ঘূর্ণন ম্যাট্রিক্স , ( প্রস্থ , উচ্চতা ) )

cv2. imshow ( 'স্বেচ্ছাচারী পয়েন্ট থেকে চিত্র ঘূর্ণন' , ঘোরানো চিত্র )

cv2. অপেক্ষা কী ( 0 )

লাইন 34 থেকে 35: এখন, একটি বস্তু ঘোরানোর জন্য এই কোডটি বেশ সাধারণ বলে মনে করা উচিত। ছবিটিকে বাম দিকে 40 পিক্সেল এবং এর কেন্দ্রের উপরে 40 পিক্সেলের চারপাশে ঘুরানোর জন্য, আমরা নির্দেশ দিই cv2.getRotationMatrix2D ফাংশন তার প্রথম পরামিতি মনোযোগ দিতে.

আমরা যখন এই ঘূর্ণনটি প্রয়োগ করি তখন উত্পাদিত চিত্রটি নীচে দেখানো হয়েছে:

আমরা স্পষ্টভাবে দেখতে পাচ্ছি যে ঘূর্ণনের কেন্দ্রটি এখন (x, y)-কোঅর্ডিনেট, যা বাম দিকে 40 পিক্সেল এবং ছবির গণনা করা কেন্দ্রের উপরে 40 পিক্সেল।

3. চিত্র পাটিগণিত

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

চলুন রৈখিক বীজগণিতের কিছু সুন্দর মৌলিক বিষয় নিয়ে যেতে একটু সময় নিই।

পরবর্তী দুটি ম্যাট্রিক্স একত্রিত করার কথা বিবেচনা করুন:

ম্যাট্রিক্স সংযোজন কী ফলাফল দেবে? সহজ উত্তর হল ম্যাট্রিক্স এন্ট্রিগুলির সমষ্টি, উপাদান দ্বারা উপাদান:

যথেষ্ট সহজ, তাই না?

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

RGB ইমেজে পিক্সেল, উদাহরণস্বরূপ, [0, 255] এর মধ্যে পড়ে। আমরা যদি 250 এর তীব্রতার সাথে একটি পিক্সেলের দিকে তাকানোর সময় 10 যোগ করার চেষ্টা করি তবে কী হবে?

যদি আমরা স্ট্যান্ডার্ড গাণিতিক নীতি প্রয়োগ করি তাহলে আমরা 260 এর মান এ পৌঁছাব। 260 একটি বৈধ মান নয়, কারণ RGB চিত্রগুলিকে 8-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা হিসাবে উপস্থাপন করা হয়।

তাহলে কি ঘটতে হবে? কোন পিক্সেল [0, 255] এর রেঞ্জের বাইরে নয় তা নিশ্চিত করার জন্য আমাদের কি একটি চেক চালানো উচিত, প্রতিটি পিক্সেলকে 0 থেকে 255 এর মধ্যে মান রাখার জন্য ক্লিপ করা উচিত?

নাকি আমরা 'চারপাশে মোড়ানো' এবং একটি মডুলাস অপারেশন সঞ্চালন? মডুলাস নিয়ম অনুসারে, 10 এর সাথে 255 যোগ করলে মাত্র 9 এর মান পাওয়া যাবে।

[0, 255] এর সীমার বাইরে চিত্রগুলিতে সংযোজন এবং বিয়োগ কীভাবে পরিচালনা করা উচিত?

সত্য যে কোন সঠিক বা ভুল কৌশল নেই; এটা সব নির্ভর করে আপনি কিভাবে আপনার পিক্সেল নিয়ে কাজ করছেন এবং আপনি কি অর্জন করবেন তার উপর।

কিন্তু মনে রাখবেন যে OpenCV-এ যোগ করা এবং NumPy-এ যোগ করার মধ্যে পার্থক্য রয়েছে। মডুলাস পাটিগণিত এবং 'র্যাপ এরাউন্ড' NumPy দ্বারা করা হবে। বিপরীতে, OpenCV ক্লিপিং চালাবে এবং নিশ্চিত করবে যে পিক্সেল মানগুলি কখনই পরিসীমা [0, 255] ত্যাগ করবে না।

নামক একটি নতুন ফাইল তৈরি করে শুরু করা যাক arithmetic.py এবং এটি খোলা:

# python arithmetic.py --image squirrel.jpg

# প্রয়োজনীয় প্যাকেজ আমদানি করা হচ্ছে

আমদানি নম্র হিসাবে যেমন

আমদানি argparse

আমদানি imutil

আমদানি cv2

# আর্গুমেন্টপার্সার অবজেক্ট তৈরি করা এবং আর্গুমেন্ট পার্স করা

apObj = argparse আর্গুমেন্ট পার্সার ( )

apObj add_argument ( '-কে' , '--ছবি' , প্রয়োজনীয় = সত্য , সাহায্য = 'চিত্র পথ' )

যুক্তি = যার ( apObj পার্স_আর্গস ( ) )

ইমেজ = cv2. imread ( যুক্তি [ 'ছবি' ] )

cv2. imshow ( 'মূল_ছবি' , ইমেজ )

'''

আমাদের পিক্সেলের মান সীমার মধ্যে থাকবে [0, 255]

যেহেতু ছবিগুলি হল NumPy অ্যারে, যা স্বাক্ষরবিহীন 8-বিট পূর্ণসংখ্যা হিসাবে সংরক্ষণ করা হয়।

cv2.add এবং cv2.subtract এর মতো ফাংশন ব্যবহার করার সময়, মানগুলি ক্লিপ করা হবে

এই পরিসরে এমনকি যদি তারা এর বাইরে থেকে যোগ বা বিয়োগ করা হয়

[0, 255] পরিসর। এখানে একটি দৃষ্টান্ত আছে:

'''


ছাপা ( 'সর্বোচ্চ 255: {}' . বিন্যাস ( str ( cv2. যোগ করুন ( যেমন uint8 ( [ 201 ] ) ,

যেমন uint8 ( [ 100 ] ) ) ) ) )

ছাপা ( 'ন্যূনতম 0: {}' . বিন্যাস ( str ( cv2. বিয়োগ ( যেমন uint8 ( [ 60 ] ) ,

যেমন uint8 ( [ 100 ] ) ) ) ) )

'''

NumPy ব্যবহার করে এই অ্যারেগুলির সাথে গাণিতিক অপারেশন করার সময়,

মানটি ক্লিপ করার পরিবর্তে চারপাশে মোড়ানো হবে

[0, 255] পরিসর। ছবি ব্যবহার করার সময়, এটি রাখা অপরিহার্য

মনে

'''


ছাপা ( 'চারপাশে মোড়ানো: {}' . বিন্যাস ( str ( যেমন uint8 ( [ 201 ] ) + যেমন uint8 ( [ 100 ] ) ) ) )

ছাপা ( 'চারপাশে মোড়ানো: {}' . বিন্যাস ( str ( যেমন uint8 ( [ 60 ] ) - যেমন uint8 ( [ 100 ] ) ) ) )

'''

আসুন আমাদের চিত্রের প্রতিটি পিক্সেলের উজ্জ্বলতা 101 দ্বারা গুণ করি।

এটি করার জন্য, আমরা আমাদের ম্যাট্রিক্সের মতো একই আকারের একটি NumPy অ্যারে তৈরি করি,

একটি দিয়ে ভরা, এবং এটিকে 101 দ্বারা গুন করুন যাতে একটি অ্যারে ভরা হয়

101s সহ। অবশেষে, আমরা দুটি ইমেজ মার্জ.

আপনি লক্ষ্য করবেন যে ছবিটি এখন 'উজ্জ্বল'।

'''


ম্যাট্রিক্স = যেমন বেশী ( ইমেজ আকৃতি , dtype = 'uint8' ) * 101

image_added = cv2. যোগ করুন ( ইমেজ , ম্যাট্রিক্স )

cv2. imshow ( 'ইমেজ ফলাফল যোগ করা হয়েছে' , image_added )

#একইভাবে, আমরা গ্রহণ করে আমাদের ভাবমূর্তি আরও গাঢ় করতে পারি

সমস্ত পিক্সেল থেকে # 60 দূরে।

ম্যাট্রিক্স = যেমন বেশী ( ইমেজ আকৃতি , dtype = 'uint8' ) * 60

চিত্র_বিয়োগ = cv2. বিয়োগ ( ইমেজ , ম্যাট্রিক্স )

cv2. imshow ( 'বিয়োগ করা ছবির ফলাফল' , চিত্র_বিয়োগ )

cv2. অপেক্ষা কী ( 0 )

লাইন 1 থেকে 16 পর্যন্ত আমাদের স্বাভাবিক প্রক্রিয়া চালানোর জন্য ব্যবহার করা হবে, যার মধ্যে আমাদের প্যাকেজ আমদানি করা, আমাদের আর্গুমেন্ট পার্সার কনফিগার করা এবং আমাদের ছবি লোড করা অন্তর্ভুক্ত।

মনে করুন কিভাবে আমি আগে OpenCV এবং NumPy যোগের মধ্যে পার্থক্য নিয়ে আলোচনা করেছি? এখন যেহেতু আমরা এটিকে পুঙ্খানুপুঙ্খভাবে কভার করেছি, আসুন আমরা এটি উপলব্ধি করতে পারি তা নিশ্চিত করার জন্য একটি নির্দিষ্ট ক্ষেত্রে দেখি।

দুটি 8-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা NumPy অ্যারে সংজ্ঞায়িত করা হয়েছে লাইন 26 . 201 এর মান হল প্রথম অ্যারের একমাত্র উপাদান। যদিও শুধুমাত্র একজন সদস্য দ্বিতীয় অ্যারেতে রয়েছে, তবে এটির মান 100। মানগুলি তারপর OpenCV-এর cv2.add ফাংশন ব্যবহার করে যোগ করা হয়।

আপনি কি ফলাফল হতে প্রত্যাশিত?

প্রচলিত গাণিতিক নীতি অনুসারে, উত্তরটি 301 হওয়া উচিত। তবে মনে রাখবেন যে আমরা 8-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা নিয়ে কাজ করছি, যা শুধুমাত্র [0, 255] পরিসরে হতে পারে। যেহেতু আমরা cv2.add পদ্ধতি ব্যবহার করছি, OpenCV ক্লিপিং পরিচালনা করে এবং নিশ্চিত করে যে সংযোজন শুধুমাত্র সর্বোচ্চ 255 ফলাফল প্রদান করে।

নীচের তালিকার প্রথম লাইনটি এই কোডটি চালানোর ফলাফল দেখায়:

পাটিগণিত py

সর্বাধিক 255 : [ [ 255 ] ]

যোগফল প্রকৃতপক্ষে 255 নম্বর তৈরি করেছে।

তা অনুসরণ করে, লাইন 26 একটি বিয়োগ সম্পাদন করতে cv2.subtract ব্যবহার করে। আরও একবার, আমরা প্রতিটিতে একটি একক উপাদান সহ দুটি 8-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা NumPy অ্যারে সংজ্ঞায়িত করি। প্রথম অ্যারের মান হল 60, যেখানে দ্বিতীয় অ্যারের মান হল 100৷

আমাদের পাটিগণিত নির্দেশ করে যে বিয়োগের ফলে একটি মান -40 হওয়া উচিত, কিন্তু OpenCV আমাদের জন্য আরও একবার ক্লিপিং পরিচালনা করে। আমরা আবিষ্কার করেছি যে মানটি 0-এ ছাঁটাই করা হয়েছে। নীচে আমাদের ফলাফল এটি প্রদর্শন করে:

পাটিগণিত py

সর্বনিম্ন 0 : [ [ 0 ] ]

cv2 ব্যবহার করে, 60 বিয়োগ থেকে 100 বিয়োগ করুন, মান 0 উৎপন্ন করুন।

কিন্তু গণনা করার জন্য যদি আমরা OpenCV-এর জায়গায় NumPy ব্যবহার করি তাহলে কী হবে?

লাইন 38 এবং 39 এই সমস্যাটি সমাধান করুন।

প্রথমত, দুটি 8-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা NumPy অ্যারে প্রতিটি একটি একক উপাদানের সাথে সংজ্ঞায়িত করা হয়েছে। প্রথম অ্যারের মান হল 201, যেখানে দ্বিতীয় অ্যারের মান হল 100৷ আমাদের সংযোজন ছাঁটাই করা হবে, এবং যদি আমরা cv2.add ফাংশনটি ব্যবহার করি তাহলে 255 এর মান ফেরত দেওয়া হবে৷

অন্যদিকে, NumPy, 'আশেপাশে মোড়ানো' এবং ক্লিপিংয়ের পরিবর্তে মডুলো পাটিগণিত করে। NumPy 255-এর মান পৌঁছানোর পরে শূন্যে মোড়ানো হয় এবং তারপর 100টি ধাপ না পৌঁছানো পর্যন্ত গণনা আবার শুরু করে। এটি আউটপুটের প্রথম লাইন দ্বারা নিশ্চিত করা হয়েছে, যা নীচে দেখানো হয়েছে:

পাটিগণিত py
চারপাশে মোড়ানো: [ চার পাঁচ ]

তারপর, আরও দুটি NumPy অ্যারে সংজ্ঞায়িত করা হয়েছে, একটির মান 50 এবং অন্যটির 100। এই বিয়োগটি cv2.subtract পদ্ধতি দ্বারা 0-এর ফলাফল ফেরাতে ছাঁটাই করা হবে। কিন্তু আমরা সচেতন যে ক্লিপিংয়ের পরিবর্তে, NumPy কার্যকর করে। মডুলো পাটিগণিত পরিবর্তে, বিয়োগের সময় 0 এ পৌঁছালে মডুলো পদ্ধতিগুলি প্রায় 255 থেকে পিছনের দিকে গণনা শুরু করে। আমরা নিম্নলিখিত আউটপুট থেকে এটি দেখতে পারি:

পাটিগণিত py

চারপাশে মোড়ানো: [ 207 ]

আরও একবার, আমাদের টার্মিনাল আউটপুট ক্লিপিং এবং চারপাশে মোড়ানোর মধ্যে পার্থক্য প্রদর্শন করে:

পূর্ণসংখ্যা পাটিগণিত সম্পাদন করার সময় আপনার পছন্দসই ফলাফলটি মাথায় রাখা গুরুত্বপূর্ণ। আপনি কি পরিসীমা [0, 255] এর বাইরে কোনো মান ক্লিপ করতে চান? এর পরে OpenCV-এর অন্তর্নির্মিত চিত্র গাণিতিক কৌশলগুলি ব্যবহার করুন।

আপনি কি চান যে মানগুলি যদি [0, 255] এবং মডুলাস গাণিতিক ক্রিয়াকলাপগুলির সীমার বাইরে থাকে তবে চারপাশে মোড়ানো হোক? NumPy অ্যারেগুলি স্বাভাবিকভাবে যোগ এবং বিয়োগ করা হয়।

লাইন 48 আমাদের চিত্রের মতো একই মাত্রা সহ একটি এক-মাত্রিক NumPy অ্যারে সংজ্ঞায়িত করে। আরও একবার, আমরা নিশ্চিত করি যে আমাদের ডেটা টাইপ 8-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যা। আমরা আমাদের এক-সংখ্যার মানগুলির ম্যাট্রিক্সকে 101 দ্বারা গুণ করি যাতে এটি 1-এর পরিবর্তে 101-এর মান দিয়ে পূরণ করা যায়৷ অবশেষে, আমরা মূল ছবিতে আমাদের 100s-এর ম্যাট্রিক্স যুক্ত করতে cv2.add ফাংশন ব্যবহার করি৷ এটি প্রতিটি পিক্সেলের তীব্রতা 101 দ্বারা বৃদ্ধি করে এবং এটি নিশ্চিত করে যে 255 ছাড়িয়ে যাওয়ার চেষ্টা করা যে কোনও মান পরিসরে ক্লিপ করা হয়েছে [0, 255]।

লক্ষ্য করুন কিভাবে চিত্রটি লক্ষণীয়ভাবে উজ্জ্বল এবং আসলটির চেয়ে বেশি 'ধুয়ে গেছে'। এর কারণ হল আমরা পিক্সেলকে 101 দ্বারা পিক্সেলের তীব্রতা বাড়িয়ে উজ্জ্বল রঙের দিকে চালিত করছি।

চিত্রের প্রতিটি পিক্সেল তীব্রতা থেকে 60 বিয়োগ করার জন্য, আমরা প্রথমে লাইন 54-এ একটি দ্বিতীয় NumPy অ্যারে স্থাপন করি যা 60s দিয়ে পূর্ণ।

এই বিয়োগের ফলাফলগুলি নিম্নলিখিত ছবিতে চিত্রিত করা হয়েছে:

আমাদের চারপাশের আইটেমগুলি আগের তুলনায় উল্লেখযোগ্যভাবে গাঢ় দেখায়। এর কারণ হল প্রতিটি পিক্সেল থেকে 60 বিয়োগ করে, আমরা আরজিবি কালার স্পেসে পিক্সেলগুলিকে গাঢ় অঞ্চলে নিয়ে যাচ্ছি।

4. ইমেজ ফ্লিপিং

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

আমরা একটি ছোট স্টার্টআপ কোম্পানীর জন্য একটি মেশিন লার্নিং ক্লাসিফায়ার তৈরি করছি যেটি চিত্রগুলিতে মুখ সনাক্ত করতে চায়৷ আমাদের সিস্টেমের জন্য একটি মুখ কি 'শিখতে' জন্য, আমাদের নমুনা মুখ সহ কিছু ধরনের ডেটাসেট প্রয়োজন। দুর্ভাগ্যবশত, কোম্পানি আমাদের শুধুমাত্র 40 মুখের একটি ছোট ডেটাসেট দিয়েছে, এবং আমরা আরও তথ্য সংগ্রহ করতে অক্ষম।

তাহলে, আমরা কি করব?

যেহেতু একটি মুখ মিরর করা হোক বা না হোক একটি মুখই থাকে, তাই আমরা একটি মুখের প্রতিটি চিত্রকে অনুভূমিকভাবে ফ্লিপ করতে এবং মিরর করা সংস্করণগুলিকে অতিরিক্ত প্রশিক্ষণ ডেটা হিসাবে ব্যবহার করতে পারি৷

এই উদাহরণটি বোকা এবং কৃত্রিম মনে হতে পারে, কিন্তু তা নয়। ফ্লিপিং হল একটি ইচ্ছাকৃত কৌশল যা শক্তিশালী গভীর-শিক্ষার অ্যালগরিদম দ্বারা প্রশিক্ষণ পর্বে আরও ডেটা তৈরি করতে ব্যবহৃত হয়।

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

উদ্দেশ্য:

ব্যবহার করে cv2.flip ফাংশন, এই সেশনে আপনি শিখবেন কিভাবে একটি ইমেজকে অনুভূমিক এবং উল্লম্বভাবে ফ্লিপ করতে হয়।

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


আমাদের আসল ছবিটি কীভাবে বাম দিকে রয়েছে এবং কীভাবে ছবিটি ডানদিকে অনুভূমিকভাবে মিরর করা হয়েছে তা নোট করুন।

নামক একটি নতুন ফাইল তৈরি করে শুরু করা যাক flipping.py .

আপনি একটি চিত্র ফ্লিপের একটি উদাহরণ দেখেছেন, তাই আসুন কোডটি পরীক্ষা করি:

# python flipping.py --image quirrel.jpg

# প্রয়োজনীয় প্যাকেজ আমদানি করা হচ্ছে

আমদানি argparse

আমদানি cv2

# আর্গুমেন্ট পার্সার অবজেক্ট তৈরি করা এবং আর্গুমেন্ট পার্স করা

apObj = argparse আর্গুমেন্ট পার্সার ( )

apObj add_argument ( '-আমি' , '--ছবি' , প্রয়োজনীয় = সত্য , সাহায্য = 'চিত্র পথ' )

যুক্তি = যার ( apObj পার্স_আর্গস ( ) )

ইমেজ = cv2. imread ( যুক্তি [ 'ছবি' ] )

cv2. imshow ( 'মূল' , ইমেজ )

# অনুভূমিকভাবে ছবিটি ফ্লিপ করুন

imageflipped = cv2. উল্টানো ( ইমেজ , 1 )

cv2. imshow ( 'ছবি অনুভূমিকভাবে উল্টানো' , imageflipped )

# উল্লম্বভাবে ছবিটি উল্টান

imageflipped = cv2. উল্টানো ( ইমেজ , 0 )

cv2. imshow ( 'উল্লম্বভাবে ছবি উল্টানো' , imageflipped )

# ছবি উভয় অক্ষ বরাবর উল্টানো

imageflipped = cv2. উল্টানো ( ইমেজ , - 1 )

cv2. imshow ( 'অনুভূমিকভাবে এবং উল্লম্বভাবে উল্টানো' , imageflipped )

cv2. অপেক্ষা কী ( 0 )

আমাদের প্যাকেজগুলি আমদানি করতে, আমাদের ইনপুটগুলি পার্স করতে এবং ডিস্ক থেকে আমাদের চিত্র লোড করার জন্য আমরা যে পদক্ষেপগুলি গ্রহণ করি তা হ্যান্ডেল করা হয় ines 1 থেকে 12 .

cv2.flip ফাংশন চালু করে লাইন 15 , অনুভূমিকভাবে একটি ছবি ফ্লিপ করা সহজ। আমরা যে ছবিটি ফ্লিপ করতে চাই এবং একটি নির্দিষ্ট কোড বা ফ্ল্যাগ যা নির্দিষ্ট করে যে ছবিটি কীভাবে ফ্লিপ করতে হয় তা হল cv2.flip পদ্ধতির জন্য দুটি আর্গুমেন্ট।

1 এর একটি ফ্লিপ কোড মান মানে হল আমরা ইমেজটিকে y-অক্ষের চারপাশে ঘুরিয়ে আনুভূমিকভাবে ফ্লিপ করব ( লাইন 15 ) যদি আমরা 0-এর একটি ফ্লিপ কোড নির্দিষ্ট করি, আমরা ইমেজটিকে x-অক্ষে ঘোরাতে চাই ( লাইন 19 ) একটি নেতিবাচক ফ্লিপ কোড ( লাইন 23 ) উভয় অক্ষে চিত্রটিকে ঘোরায়।

এই বিষয়ের সবচেয়ে সহজ উদাহরণগুলির মধ্যে একটি হল একটি ছবি ফ্লিপ করা, যা মৌলিক।

এর পরে, আমরা চিত্রগুলি কাটার বিষয়ে আলোচনা করব এবং নির্দিষ্ট চিত্রের অংশগুলি বের করতে NumPy অ্যারে স্লাইসগুলি ব্যবহার করব।

5. ছবি ক্রপিং

ক্রপিং, নাম থেকে বোঝা যায়, আগ্রহের অঞ্চল (বা কেবলমাত্র ROI) বেছে নেওয়া এবং অপসারণের প্রক্রিয়া, যা আমাদের আগ্রহের চিত্রের এলাকা।

একটি মুখ সনাক্তকরণ অ্যাপ্লিকেশনের জন্য একটি চিত্র থেকে মুখটি কাটতে হবে। অতিরিক্তভাবে, আমরা যদি চিত্রগুলিতে কুকুরগুলি খুঁজে পাওয়ার জন্য একটি পাইথন স্ক্রিপ্ট তৈরি করি, আমরা কুকুরটিকে সনাক্ত করার সময় ছবিটি থেকে ক্রপ করতে চাই।

লক্ষ্য: আমাদের মূল লক্ষ্য হল NumPy অ্যারে স্লাইসিং ব্যবহার করে একটি ইমেজ থেকে এলাকা কাটানোর সাথে পরিচিত হওয়া এবং স্বাচ্ছন্দ্যে পরিচিত হওয়া।

ক্রপিং : যখন আমরা একটি ছবি ক্রপ করি, তখন আমাদের লক্ষ্য হল বাহ্যিক উপাদানগুলিকে বাদ দেওয়া যা আমাদের আগ্রহী নয়৷ আমাদের ROI নির্বাচন করার প্রক্রিয়াটিকে প্রায়শই আমাদের আগ্রহের অঞ্চল বেছে নেওয়া হিসাবে উল্লেখ করা হয়।

নামে একটি নতুন ফাইল তৈরি করুন crop.py , এটি খুলুন, এবং নিম্নলিখিত কোড যোগ করুন:

# python crop.py

# প্রয়োজনীয় প্যাকেজ আমদানি করা হচ্ছে

আমদানি cv2

# চিত্র লোড এবং পর্দায় প্রদর্শন

ইমেজ = cv2. imread ( 'squirrel.jpg' )

ছাপা ( ইমেজ আকৃতি )

cv2. imshow ( 'মূল' , ইমেজ )

# NumPy অ্যারে স্লাইসগুলি একটি চিত্র দ্রুত ট্রিম করতে ব্যবহৃত হয়

# আমরা চিত্র থেকে কাঠবিড়ালি মুখ ক্রপ করতে যাচ্ছি

কাঠবিড়ালি = ইমেজ [ 35 : 90 , 35 : 100 ]

cv2. imshow ( 'কাঠবিড়ালি মুখ' , কাঠবিড়ালি )

cv2. অপেক্ষা কী ( 0 )

#এবং এখন, এখানে আমরা পুরো শরীর ক্রপ করতে যাচ্ছি

# কাঠবিড়ালি

কাঠবিড়ালি = ইমেজ [ 35 : 148 , 23 : 143 ]

cv2. imshow ( 'কাঠবিড়ালির শরীর' , কাঠবিড়ালি )

cv2. অপেক্ষা কী ( 0 )

আমরা পাইথন এবং ওপেনসিভিতে একটি চিত্র ব্যবহার করে ক্রপিং দেখাব যা আমরা ডিস্ক থেকে লোড করি লাইন 5 এবং 6 .

আসল চিত্র যা আমরা ক্রপ করতে যাচ্ছি

শুধুমাত্র মৌলিক ফসলের কৌশল ব্যবহার করে, আমরা কাঠবিড়ালী মুখ এবং কাঠবিড়ালির দেহকে আশেপাশের এলাকা থেকে আলাদা করার লক্ষ্য রাখি।

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

আমরা কোডের মাত্র একটি লাইন দিয়ে ছবিতে মুখটি সনাক্ত করতে পারি। লাইন 13 , (35, 35) থেকে শুরু করে ছবির একটি আয়তক্ষেত্র অংশ বের করতে, আমরা NumPy অ্যারে স্লাইস (90, 100) প্রদান করি। এটা বিভ্রান্তিকর মনে হতে পারে যে আমরা উচ্চতা-প্রথম এবং প্রস্থ-দ্বিতীয় ক্রমে সূচী দিয়ে ফসল খাওয়াই, কিন্তু মনে রাখবেন যে OpenCV ছবিগুলিকে NumPy অ্যারে হিসাবে সংরক্ষণ করে। ফলস্বরূপ, আমাদের অবশ্যই x-অক্ষের আগে y-অক্ষের মান সরবরাহ করতে হবে।

আমাদের ক্রপিং করার জন্য NumPy-এর নিম্নলিখিত চারটি সূচক প্রয়োজন:

শুরু y: শুরুতে y-সমন্বয়। এই উদাহরণের জন্য, আমরা y=35 এ শুরু করি।

শেষ y: শেষে y সমন্বয়. y = 90 হলে আমাদের ফসল থামবে।

শুরু x: স্লাইসের শুরু x স্থানাঙ্ক। ফসল শুরু হয় x=35 এ।

শেষ x: স্লাইসের শেষের x-অক্ষ স্থানাঙ্ক। x=100 এ, আমাদের স্লাইস শেষ।

একইভাবে, আমরা মূল চিত্র থেকে অঞ্চলগুলি (23, 35) এবং (143, 148) ক্রপ করি লাইন 19 .

আপনি লক্ষ্য করতে পারেন যে ছবিটি শুধুমাত্র শরীর এবং মুখ প্রদর্শন করার জন্য ক্রপ করা হয়েছে।

6. ইমেজ রিসাইজ করা

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

আমাদের প্রাথমিক চিত্র বাম দিকে। ডানদিকে, আপনি দুটি চিত্র দেখতে পাবেন যেগুলি আকৃতির অনুপাত বজায় না রেখে স্কেল করা হয়েছে, চিত্রের প্রস্থের উচ্চতার অনুপাতকে বিকৃত করে। আপনার ছবির আকার পরিবর্তন করার সময়, আপনার সাধারণত আকৃতির অনুপাত বিবেচনা করা উচিত।

আমাদের রিসাইজিং অ্যালগরিদম দ্বারা ব্যবহৃত ইন্টারপোলেশন কৌশলটি অবশ্যই চিত্রের আকার বাড়াতে বা কমাতে পিক্সেলের এই পার্শ্ববর্তী অঞ্চলগুলি ব্যবহার করার জন্য ইন্টারপোলেশন ফাংশনের উদ্দেশ্য বিবেচনা করতে হবে।

সাধারণভাবে, ছবির আকার সঙ্কুচিত করা অনেক বেশি কার্যকর। এর কারণ হল একটি ইমেজ থেকে পিক্সেল অপসারণ করা সমস্ত ইন্টারপোলেশন ফাংশন যা করতে হবে। অন্যদিকে, ইন্টারপোলেশন পদ্ধতির জন্য পিক্সেলগুলির মধ্যে 'শূন্যস্থান পূরণ' করতে হবে যা পূর্বে বিদ্যমান ছিল না যদি চিত্রের আকার বাড়াতে হয়।

বাম দিকে আমাদের আসল ছবি আছে। ছবিটি কেন্দ্রে তার আসল আকারের অর্ধেক কমিয়ে আনা হয়েছে, তবে তা ছাড়া, ছবির 'গুণমানের' কোন ক্ষতি হয়নি। তবুও, ছবির আকার ডানদিকে যথেষ্ট বৃদ্ধি করা হয়েছে। এটি এখন 'বিস্ফোরিত' এবং 'পিক্সেলেড' দেখা যাচ্ছে।

যেমনটি আমি আগে বলেছি, আপনি সাধারণত একটি চিত্রের আকার বাড়ানোর পরিবর্তে কমাতে চান। ছবির আকার কমিয়ে, আমরা কম পিক্সেল বিশ্লেষণ করি এবং কম 'শব্দ' মোকাবেলা করতে হয়, যা চিত্র প্রক্রিয়াকরণ অ্যালগরিদমগুলিকে দ্রুত এবং আরও সুনির্দিষ্ট করে তোলে৷

অনুবাদ এবং ঘূর্ণন হল দুটি চিত্র রূপান্তর যা এখন পর্যন্ত সম্বোধন করা হয়েছে। আমরা এখন পরীক্ষা করব কিভাবে একটি ইমেজ রিসাইজ করা যায়।

আশ্চর্যজনকভাবে, আমরা cv2.resize পদ্ধতি ব্যবহার করে আমাদের চিত্রের আকার পরিবর্তন করব। আমি আগে ইঙ্গিত করেছি, এই পদ্ধতিটি ব্যবহার করার সময় আমাদের অবশ্যই চিত্রের আকৃতির অনুপাত বিবেচনা করতে হবে। কিন্তু আমরা সুনির্দিষ্টভাবে খুব গভীরভাবে প্রবেশ করার আগে, আমাকে আপনাকে একটি উদাহরণ দেওয়ার অনুমতি দিন:

# python resize.py --image squirrel.jpg

# প্রয়োজনীয় প্যাকেজ আমদানি করা হচ্ছে

আমদানি argparse

আমদানি cv2

# আর্গুমেন্ট পার্সার অবজেক্ট তৈরি করা এবং আর্গুমেন্ট পার্স করা

apObj = argparse আর্গুমেন্ট পার্সার ( )

apObj add_argument ( '-কে' , '--ছবি' , প্রয়োজনীয় = সত্য , সাহায্য = 'চিত্র পথ' )

যুক্তি = যার ( apObj পার্স_আর্গস ( ) )

# চিত্রটি লোড করুন এবং পর্দায় প্রদর্শন করুন

ইমেজ = cv2. imread ( যুক্তি [ 'ছবি' ] )

cv2. imshow ( 'মূল' , ইমেজ )

# যাতে চিত্রটিকে তির্যক দেখাতে না পারে সেজন্য, আকৃতির অনুপাত

# বিবেচনা বা বিকৃত করা আবশ্যক; অতএব, আমরা কি চিন্তা

# বর্তমান চিত্রের সাথে নতুন চিত্রের অনুপাত।

# আসুন আমাদের নতুন ছবির প্রস্থ 160 পিক্সেল করি।

দৃষ্টিভঙ্গি = 160.0 / চিত্র। আকৃতি [ 1 ]

মাত্রা = ( 160 , int ( ইমেজ আকৃতি [ 0 ] * দৃষ্টিভঙ্গি ) )

# এই লাইনটি প্রকৃত আকার পরিবর্তনের ক্রিয়াকলাপ দেখাবে

চিত্রের আকার পরিবর্তন করুন = cv2. আকার পরিবর্তন করুন ( ইমেজ , মাত্রা , ইন্টারপোলেশন = cv2. INTER_AREA )

cv2. imshow ( 'ছবির প্রস্থের আকার পরিবর্তন করুন' , চিত্রের আকার পরিবর্তন করুন )

# যদি আমরা ছবির উচ্চতা পরিবর্তন করতে চাই? - ব্যবহার করে

# একই নীতি, আমরা আকৃতির অনুপাত ভিত্তিক গণনা করতে পারি

# প্রস্থের চেয়ে উচ্চতায়। এর স্কেল করা যাক

# ছবির উচ্চতা 70 পিক্সেল।

দৃষ্টিভঙ্গি = 70.0 / চিত্র। আকৃতি [ 0 ]

মাত্রা = ( int ( ইমেজ আকৃতি [ 1 ] * দৃষ্টিভঙ্গি ) , 70 )

# আকার পরিবর্তন করুন

চিত্রের আকার পরিবর্তন করুন = cv2. আকার পরিবর্তন করুন ( ইমেজ , মাত্রা , ইন্টারপোলেশন = cv2. INTER_AREA )

cv2. imshow ( 'ছবির উচ্চতা মাপ পরিবর্তন করুন' , চিত্রের আকার পরিবর্তন করুন )

cv2. অপেক্ষা কী ( 0 )

লাইন 1-14 , আমাদের প্যাকেজ আমদানি করার পরে এবং আমাদের আর্গুমেন্ট পার্সার কনফিগার করার পরে, আমরা আমাদের ছবি লোড এবং প্রদর্শন করব।

লাইন 20 এবং 21: প্রাসঙ্গিক কোডিং এই লাইনগুলিতে শুরু হয় . এটির আকার পরিবর্তন করার সময় চিত্রটির আকৃতির অনুপাত অবশ্যই বিবেচনায় নেওয়া উচিত। চিত্রের প্রস্থ এবং উচ্চতার মধ্যে অনুপাতকে আকৃতির অনুপাত বলা হয়।

উচ্চতা প্রস্থ হল আকৃতির অনুপাত।

আমরা যদি আকৃতির অনুপাতকে বিবেচনায় না নিই, তাহলে আমাদের আকার পরিবর্তনের ফলাফলগুলি বিকৃত হয়ে যাবে।

চালু লাইন 20 , পুনরায় আকার অনুপাত গণনা করা হয়. আমরা কোডের এই লাইনে আমাদের নতুন ছবির প্রস্থ 160 পিক্সেল হিসাবে প্রদান করি। আমরা কেবল আমাদের অনুপাত (অ্যাস্পেক্ট্রেশিও) কে নতুন প্রস্থ (160 পিক্সেল) পুরানো প্রস্থ দ্বারা বিভক্ত হিসাবে সংজ্ঞায়িত করি, যা আমরা চিত্র ব্যবহার করে অ্যাক্সেস করি, নতুন উচ্চতার সাথে পুরানো উচ্চতার অনুপাত গণনা করতে। আকৃতি [1]।

ছবির নতুন মাত্রা চালু লাইন 21 এখন গণনা করা যেতে পারে যে আমরা আমাদের অনুপাত জানি। আরও একবার, নতুন চিত্রটির প্রস্থ 160 পিক্সেল হবে। আমাদের অনুপাত দ্বারা পুরানো উচ্চতা গুণ করার পরে এবং ফলাফলটিকে একটি পূর্ণসংখ্যাতে রূপান্তর করার পরে, উচ্চতা গণনা করা হয়। আমরা এই ক্রিয়াকলাপটি চালিয়ে ছবির আসল আকৃতির অনুপাত বজায় রাখতে পারি।

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

অবশেষে, অন লাইন 25 , আমরা আমাদের স্কেল করা চিত্র প্রদর্শন করি।

আমরা আমাদের অনুপাত (অনুপাত) পুনরায় সংজ্ঞায়িত করি লাইন 31 . আমাদের নতুন ছবির উচ্চতা হবে ৭০ পিক্সেল। নতুন উচ্চতা থেকে আসল উচ্চতা অনুপাত পেতে আমরা 70 কে মূল উচ্চতা দিয়ে ভাগ করি।

এর পরে, আমরা নতুন চিত্রের মাত্রা স্থাপন করি। নতুন চিত্রটির উচ্চতা 70 পিক্সেল হবে, যা ইতিমধ্যেই জানা গেছে। আমরা নতুন প্রস্থ তৈরি করতে পুরানো প্রস্থকে অনুপাত দ্বারা গুণ করে চিত্রের আসল আকৃতির অনুপাতকে আরও একবার রাখতে পারি।

চিত্রটি আসলে পুনরায় আকার দেওয়া হয় লাইন 35 , এবং এটি প্রদর্শিত হয় লাইন 36।

এখানে, আমরা দেখতে পাচ্ছি যে আমরা আকৃতির অনুপাত বজায় রেখে আমাদের আসল চিত্রের প্রস্থ এবং উচ্চতা হ্রাস করেছি। আকৃতির অনুপাত বজায় না থাকলে আমাদের ছবিটি বিকৃত দেখাবে।

উপসংহার

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

এই বিভাগে যোগ এবং বিয়োগের দুটি মৌলিক (কিন্তু তাৎপর্যপূর্ণ) চিত্র গাণিতিক ক্রিয়াকলাপ পরীক্ষা করা হয়েছিল। আপনি দেখতে পাচ্ছেন, মৌলিক ম্যাট্রিক্স যোগ করা এবং বিয়োগ করা সমস্ত চিত্রের গাণিতিক ক্রিয়াকলাপগুলিকে অন্তর্ভুক্ত করে।

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

এটি মনে রাখা গুরুত্বপূর্ণ যে যদিও NumPy একটি মডুলাস অপারেশন করে এবং 'আশেপাশে মোড়ানো' করে, তবে রেঞ্জের ভিতরে ফিট করার জন্য OpenCV যোগ এবং বিয়োগ করা মানগুলি পরিসীমা [0, 255] ছাড়িয়ে যায়। আপনার নিজস্ব কম্পিউটার ভিশন অ্যাপ্লিকেশন বিকাশ করার সময়, এটি মনে রাখা আপনাকে জটিল বাগগুলি এড়াতে সহায়তা করবে।

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

আমরা একটি ইমেজ রিসাইজ করতে ওপেনসিভি ব্যবহার করতে শিখেছি। আপনি যে ইন্টারপোলেশন পদ্ধতিটি নিযুক্ত করছেন এবং আপনার আসল চিত্রটির আকারের অনুপাত উভয়ই বিবেচনা করা গুরুত্বপূর্ণ যাতে ফলাফলটি বিকৃত না হয়।

অবশেষে, এটি মনে রাখা গুরুত্বপূর্ণ যে যদি ছবির গুণমান একটি সমস্যা হয়, তবে একটি বড় থেকে একটি ছোট ছবিতে পরিবর্তন করা সর্বদা ভাল৷ বেশিরভাগ ক্ষেত্রে, একটি চিত্র বড় করা শিল্পকর্ম তৈরি করে এবং এর গুণমানকে হ্রাস করে।