বাস্তবে COLMAP

11 minute read

Published:

মূল ধারাবাহিক থেকে সরে এসে একটি লেখা, দুই ভাগে। প্রথম ভাগ কোনো পূর্বজ্ঞান ধরে না নিয়েই বলে Structure-from-Motion আর COLMAP জিনিসটা কী; দ্বিতীয় ভাগ হাতেকলমে খুঁটিনাটি, যাঁদের সত্যিই এটি চালাতে হয় তাঁদের জন্য। কেবল ধারণাটুকু চাইলে “চারটি ধাপ” পর্যন্ত পড়ে থেমে যান। স্কেল ছাড়া মাপা নিয়ে প্রতিশ্রুত লেখাটি এরপরেই আসছে।

শুরু করা যাক পর্যটকে ভরা একটি চত্বর দিয়ে

ব্যস্ত এক বিকেলে শহরের চত্বরে দাঁড়ানো একটি ভাস্কর্যের কথা ভাবুন। দুইশো মানুষ তার ছবি তুলছে — সিঁড়ি থেকে, ক্যাফের বারান্দা থেকে, একেবারে কাছ থেকে, রাস্তার ওপার থেকে। কেউ কারও সঙ্গে পরামর্শ করছে না। এরপর সেই দুইশো ছবিই এসে জমা হয় একটিমাত্র ফোল্ডারে।

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

Structure-from-Motion হলো কম্পিউটারের ঠিক সেই কাজটিই করা — আপনাআপনি, এবং আপনার চেয়ে বহুগুণ নিখুঁতভাবে। ফোল্ডারটি দিন, সে একসঙ্গে দুটি জিনিস উদ্ধার করবে:

  • প্রতিটি ছবি কোথা থেকে তোলা হয়েছিল, আর
  • সবাই যেদিকে তাক করেছিল, সেই বস্তুটির ত্রিমাত্রিক আকৃতি।

নামটিই পদ্ধতির বর্ণনা: ক্যামেরা এক শট থেকে পরের শটে সরে যাওয়ার (motion) ভেতর দিয়ে আকৃতি (structure) উদ্ধার করা। এটি আদৌ কেন কাজ করে তা আগের লেখায় আছে; সংক্ষেপে, এটি সেই একই কৌশল যা আপনার দুই চোখ প্রতি মুহূর্তে খেলে যাচ্ছে।

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

COLMAP হলো সেই প্রোগ্রাম, যে কাজটি করে

COLMAP হলো সেই ওপেন-সোর্স সফটওয়্যার প্যাকেজ যা Structure-from-Motion চালায়; Johannes Schönberger ও Jan-Michael Frahm-এর ২০১৬ সালের একটি গবেষণাপত্রের সঙ্গে এটি প্রকাশিত হয়। প্রায় এক দশক ধরে এটিই স্বাভাবিক পছন্দ। এটিই একমাত্র বিকল্প নয়, কিন্তু বাকি সবকিছু নিঃশব্দে ধরে নেয় আপনি এটিই ব্যবহার করেছেন।

এটি একটিমাত্র বোতাম নয়। এটি গুটিকয় কমান্ড-লাইন ধাপ, যেগুলো ক্রমানুসারে চালাতে হয়, আর প্রতিটি ধাপ তার ফল একটি সাঝা ডেটাবেস ফাইলে লিখে রাখে — পরের ধাপ সেখান থেকেই তুলে নেয়।

এই ব্লগের জন্য এটি জরুরি, কারণ আমার জানা প্রতিটি 3D Gaussian Splatting পাইপলাইন এখান থেকেই শুরু হয়। স্প্ল্যাটের লেখাটি যে বিন্দুমেঘকে কাঁচামাল ধরে নিয়েছিল, বাস্তবে সেটি COLMAP-এরই আউটপুট। ক্যামেরার অবস্থানগুলোও তাই — আর সেগুলো ঠিক ততটাই জরুরি, কারণ স্প্ল্যাট অপ্টিমাইজারকে জানতে হয় ছবিটি কোথা থেকে তোলা, তবেই সে নিজের আঁকা ছবির সঙ্গে তাকে মেলাতে পারে।

চারটি ধাপ, সহজ কথায়

ক্রমানুসারে চারটি ধাপ: প্রতিটি ছবিতে চোখে পড়ার মতো জায়গাগুলো চিহ্নিত করা; দুটি ছবির কোন চিহ্নগুলো একই বাস্তব বস্তু তা ঠিক করা; কোন ক্যামেরা কোথায় ছিল আর কোন বিন্দু কোথায় বসে তা সমাধান করা; লেন্সের বাঁক সোজা করা।
ক্রমানুসারে চারটি ধাপ। প্রথম দুটি কেবল ছবির দিকেই তাকায়; তৃতীয়টিতে এসে ত্রিমাত্রিক জ্যামিতি অবশেষে দেখা দেয়; আর চতুর্থটি পরের সরঞ্জামের জন্য গোছগাছ।
  1. চোখে পড়ার মতো জায়গা খুঁজে বের করা। প্রতিটি ছবিকে আলাদাভাবে দেখে সেই জায়গাগুলো চিহ্নিত করা যেগুলো এতটাই স্বতন্ত্র যে পরে আবার চেনা যাবে — একটি কোণ, একটি ছোপ, পাথরের ভাঙা অংশ। মসৃণ, ফাঁকা অঞ্চল থেকে কিছুই মেলে না।
  2. মিলিয়ে নেওয়া। ছবি দুটি দুটি করে নিয়ে ঠিক করা, একটির কোন চিহ্নটি অন্যটির কোন চিহ্নের সঙ্গে একই ভৌত বস্তু।
  3. সমাধান করা। এমন হাজার হাজার মিল হাতে থাকলে, ক্যামেরা আর ত্রিমাত্রিক বিন্দুগুলোর একটিমাত্র বিন্যাসই সেগুলোর সব ব্যাখ্যা করে। সেটিই বের করা।
  4. গুছিয়ে দেওয়া। লেন্স সরলরেখাকে যেভাবে বাঁকায় তা সরিয়ে ছবিগুলো নতুন করে লেখা, যাতে পরের সরঞ্জামগুলো একটি সরল, আদর্শ ক্যামেরা ধরে নিতে পারে।

আনুষঙ্গিক হিসাবনিকাশ বাদ দিলে, সেটিই এই চারটি কমান্ড:

colmap feature_extractor \
    --database_path  colmap/database.db \
    --image_path     colmap/images \
    --ImageReader.single_camera 1 \
    --FeatureExtraction.use_gpu 1

colmap exhaustive_matcher \
    --database_path  colmap/database.db \
    --FeatureMatching.use_gpu 1

colmap mapper \
    --database_path  colmap/database.db \
    --image_path     colmap/images \
    --output_path    colmap/sparse \
    --Mapper.max_num_models=1 \
    --Mapper.init_min_tri_angle=4 \
    --Mapper.filter_min_tri_angle=0.5

colmap image_undistorter \
    --image_path     colmap/images \
    --input_path     colmap/sparse/0 \
    --output_path    colmap/undistorted

লেখার বাকিটা অপশন নিয়ে, কারণ মজার সিদ্ধান্তগুলো ওখানেই লুকিয়ে আছে।

single_camera — যা জানেন, তা বলে দিন

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

এই ফ্ল্যাগটি ঠিক তাই। --ImageReader.single_camera 1 ঘোষণা করে যে সব ছবি একই ভৌত ক্যামেরা থেকে, একই সেটিংসে এসেছে — অর্থাৎ তারা একই অন্তর্গত প্যারামিটার ভাগ করে নেয়: ফোকাল দৈর্ঘ্য, মুখ্য বিন্দু, আর লেন্স বিকৃতি।

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

উল্টো দিকটাও আছে: মাঝপথে যদি লেন্স বদলে থাকেন বা জুম করে থাকেন, তবে এই ফ্ল্যাগটি একটি মিথ্যা, আর সে নিঃশব্দে আপনার পুনর্গঠনকে বাঁকিয়ে দেবে। নিশ্চিত হয়ে নেওয়াই ভালো।

মেলানো — যে ধাপটি সময় খায়

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

এ কারণেই সময় যায় মেলানোতে, বৈশিষ্ট্য নিষ্কাশনে নয়। একটি ছবির ভেতরে চোখে পড়ার মতো জায়গা খুঁজে বের করা দ্রুত, আর সবগুলো ছবির জন্য একসঙ্গেই করা যায়। কিন্তু কোন ছবির সঙ্গে কোন ছবির মিল আছে — এই প্রশ্নের কোনো সস্তা উত্তর নেই।

বৃত্তাকারে সাজানো ষোলোটি ছবি। বাঁয়ে সর্বজোড়া মেলানোতে প্রতিটি জোড়ার মধ্যে রেখা টানা, ফলে ঘন জট; ডানে ক্রমিক মেলানোতে প্রতিটি ছবি কেবল ধারণক্রমে কাছের ছবিগুলোর সঙ্গে যুক্ত, ফলে বৃত্তজুড়ে সরু একটি বলয়।
সর্বজোড়া মেলানো প্রতিটি জোড়া মিলিয়ে দেখে — পুঙ্খানুপুঙ্খ, কিন্তু বর্গীয় হারে বাড়ে। ক্রমিক মেলানো এই সত্যটি কাজে লাগায় যে ভিডিওর ফ্রেম ক্রমানুসারে আসে, তাই প্রতিটি ফ্রেমকে কেবল সময়ে কাছের ফ্রেমগুলোর সঙ্গেই মেলায়।

exhaustive_matcher প্রতিটি জোড়াই চেষ্টা করে। N সংখ্যক ছবির জন্য তা N(N−1)/2 বার তুলনা — ২০০ ছবিতে ঠিকঠাক, ১,০০০-এ অস্বস্তিকর, ৫,০০০-এ অসম্ভব। আবার এটিই সবচেয়ে নিরাপদ বিকল্প, কারণ কোনো মিল তার চোখ এড়াতে পারে না।

sequential_matcher ধরে নেয় ছবিগুলো ধারণক্রমে সাজানো — ভিডিও থেকে কাটা হলে সত্যিই তাই — আর প্রতিটি ফ্রেমকে কেবল তার প্রতিবেশীদের একটি জানালার সঙ্গে মেলায়:

colmap sequential_matcher \
    --database_path colmap/database.db \
    --SequentialMatching.overlap 30 \
    --FeatureMatching.use_gpu 1

আমি ফ্রেমসংখ্যা দেখে দুটির মধ্যে বেছে নিই — কয়েকশো পর্যন্ত সর্বজোড়া, তার বেশি হলে ক্রমিক। ক্রমিক মেলানো সম্পর্কে জেনে রাখার বিষয়টি হলো, সে কেবল সময়ে-সংলগ্ন জোড়াই দেখে। গাছের চারপাশে পুরো এক পাক ঘুরলে শেষ ফ্রেম আর প্রথম ফ্রেম স্থানে মিলে যায়, কিন্তু ক্রমে বহু দূরে থাকে। ওই বৃত্তটি আর বন্ধ হয় না, আর পুনর্গঠন পুরো পাক ঘুরে সরে যেতে পারে — টেনে জোড়া লাগানোর কিছুই থাকে না। ঠিক এর জন্যই COLMAP-এ vocabulary tree দিয়ে লুপ শনাক্তকরণ আছে; চারপাশে ঘুরে তোলা ধারণে ক্রমিক ব্যবহার করলে সেটি চালু করে নিন।

mapper, আর ত্রিভুজায়ন কোণ

mapper-ই আসল Structure-from-Motion সলভার। সে প্রথমে একটি ভালো প্রাথমিক জোড়া বাছে, সেই দুইয়ের মাঝে বিন্দু ত্রিভুজায়ন করে, তারপর বাকি ছবিগুলোকে একটি একটি করে নথিভুক্ত করে — আর মাঝে মাঝে বান্ডল অ্যাডজাস্টমেন্ট চালিয়ে সবকিছুর সঙ্গতি ধরে রাখে।

আমার দুটি অপশন ত্রিভুজায়ন কোণ নিয়ে। দৈনন্দিন ভাষায় ব্যাপারটা এই রকম। আপনার দুই চোখ প্রায় ছয় সেন্টিমিটার দূরে বসানো, আর ওই ফাঁকটুকুই আপনাকে দূরত্ব বুঝতে দেয়। এবার ভাবুন চোখ দুটি যদি মাত্র দুই মিলিমিটার দূরে থাকত। দুই চোখেই ঘরটা দিব্যি দেখা যেত — কিন্তু দুটি দৃশ্য এতই কাছাকাছি হতো যে কোনটা কাছে আর কোনটা দূরে, সে বোধ প্রায় থাকতই না।

দুটি দৃষ্টিকোণ যে বস্তুটির দিকে তাকিয়ে আছে, সেই বস্তুর কাছে তাদের মধ্যেকার কোণটিই ত্রিভুজায়ন কোণ, আর মানেটা ঠিক এটাই: ছোট কোণ মানে গভীরতা নিয়ে দুর্বল মতামত।

তাই --Mapper.init_min_tri_angle=4 দাবি করে যে প্রাথমিক জোড়ার — যে দুটির উপর COLMAP বাকি সব দাঁড় করাবে — দুই ক্যামেরার মধ্যে অন্তত চার ডিগ্রি থাকতে হবে। প্রায় একই দৃষ্টিকোণের দুটি ছবি চমৎকারভাবে মিলে যেতে পারে, অথচ গভীরতা নিয়ে প্রায় কিছুই বলে না: রশ্মি দুটি প্রায় সমান্তরাল, ফলে ছবিতে সামান্য ভুলও ছেদবিন্দুটিকে অনেক দূরে সরিয়ে দেয়। সেখান থেকে শুরু করা মানেই এমন এক পুনর্গঠন পাওয়া যা দেখতে বিশ্বাসযোগ্য, অথচ ভুল।

--Mapper.filter_min_tri_angle=0.5 একই ভাবনার পরবর্তী প্রয়োগ — যেসব বিন্দুর পর্যবেক্ষণ সমান্তরালের এত কাছাকাছি যে ভরসা করা যায় না, সেগুলো বাদ দেওয়া।

--Mapper.max_num_models=1 অন্য ধরনের সিদ্ধান্ত। একটি জিগস পাজলের কথা ভাবুন, যেখানে দুটি গুচ্ছ আলাদা আলাদা করে সুন্দর জোড়া লেগেছে, কিন্তু গুচ্ছ দুটিকে জোড়ার কিছুই নেই — শেষ পর্যন্ত হাতে থাকল দুটি দ্বীপ, আর একে অন্যের সাপেক্ষে কোথায় বসে তা জানার উপায় নেই। যে ছবিগুলোকে সে একটিমাত্র সঙ্গতিপূর্ণ দৃশ্যে জুড়তে পারে না, সেগুলো দিলে COLMAP দিব্যি ঠিক তা-ই ধরিয়ে দেবে: দুটি বা তিনটি আলাদা মডেল। এটি COLMAP-এর সততা — সংযোগগুলো সত্যিই ছিল না। কিন্তু আমার কাজের জন্য টুকরো হয়ে যাওয়া ধারণ মানেই ব্যর্থ ধারণ, আর অর্ধেক গাছ-ঢাকা স্প্ল্যাট হাতে পাওয়ার পরে জানার চেয়ে তখনই জেনে যাওয়া ভালো।

গাছের বেলায় সে কোথায় হোঁচট খায়

উপরের পরামর্শ যেকোনো দৃশ্যের জন্যই খাটে। গাছ তার নিজস্ব সমস্যা যোগ করে, আর সেগুলোর সবকটিই একটিমাত্র ধারণায় গিয়ে ঠেকে: Structure-from-Motion ধরে নেয় দৃশ্যটি অনড় ও স্থির।

চত্বরের ভাস্কর্যটি আদর্শ বিষয়বস্তু ঠিক এই কারণেই যে সে নড়ে না। এবার ভাবুন পর্যটকেরা এমন কিছুর ছবি তুলছে যা মোটেই সহযোগিতা করছে না — বাজারের ব্যস্ত একটি দোকান, যেখানে এক ছবি আর পরের ছবির মাঝে ক্রেটগুলো নতুন করে সাজানো হয়েছে আর অর্ধেক মালামাল বিক্রি হয়ে গেছে। দুটি ছবিতে “একই জিনিস” চেনার মানেটাই বদলে যায়, আর পুরো পদ্ধতিটি নিজের সঙ্গেই লড়তে শুরু করে।

গাছ হলো সেই বাজারের দোকানেরই নরম একটি সংস্করণ।

পাতা নড়ে। গ্রিনহাউসে ভেন্টিলেশন ফ্যান আছে, বাতাসের স্রোত আছে, আর আছে এত হালকা পাতা যে দুটোতেই সাড়া দেয়। কয়েক সেকেন্ড ব্যবধানের দুটি ফ্রেমের মাঝে পাতাটি আকার বদলে ফেলেছে। ওই মিলটি এখন দৃশ্যের প্রতিটি স্থির বিন্দুর সঙ্গে জ্যামিতিকভাবে অসঙ্গত, আর সমাধানে সে ঢোকে বহিঃস্থ মান হিসেবে। RANSAC কিছুটা শুষে নেয়। মাত্রা ছাড়ালে নথিভুক্তি স্রেফ ব্যর্থ হয়। বাস্তব উত্তরটি নিতান্ত সাদামাটা: দ্রুত ধারণ করুন, আর ফ্যান বন্ধ থাকতে ধারণ করুন।

পাতা বৈশিষ্ট্য হিসেবে দুর্বল। মসৃণ ঢালের, চিহ্নহীন সবুজ তল থেকে খুব কম কি-পয়েন্ট মেলে। COLMAP বরং আঁকড়ে ধরে মাটির বুনট, টবের কিনারা, গাছের লেবেল, বেঞ্চের ধার আর গ্রিনহাউসের এলোমেলো জিনিসপত্র। ক্যামেরার অবস্থান বের করতে সাধারণত এটুকুই যথেষ্ট — আর আপনার দরকার তো সেটাই — তবে গাছের উপরে বিন্দুমেঘ প্রায়ই নতুনদের প্রত্যাশার চেয়ে অনেক পাতলা হয়। ফসলের উপর কম বিন্দু থাকা মানেই ব্যর্থতা নয়।

গ্রিনহাউস নিজেকেই বারবার ফিরিয়ে আনে। একই রকম টব, একই ট্রে, সমান দূরত্বের বেঞ্চ, পুনরাবৃত্ত কাঠামো। পুনরাবৃত্ত গঠনই আত্মবিশ্বাসী ভুল-মিল পাওয়ার চিরায়ত উপায়, আর আত্মবিশ্বাসী ভুল-মিল এমন পুনর্গঠন বানায় যা স্থানীয়ভাবে পরিচ্ছন্ন আর সামগ্রিকভাবে ভাঁজ খাওয়া।

কাচ আর আকাশ। গ্রিনহাউসের কাচ ভেদ করে আসা পেছনের আলো পাতার সূক্ষ্মতা ধুইয়ে দেয় আর অটো-এক্সপোজারকে ফ্রেমে ফ্রেমে দোলায়। ঝলমলে প্রতিফলন ক্যামেরার সঙ্গে সঙ্গে সরে — অর্থাৎ সেগুলো এমন বৈশিষ্ট্য যা গঠনগতভাবেই স্থির-দৃশ্যের ধারণা ভাঙে।

ফলাফল পড়া

স্প্ল্যাটিং-এ GPU-ঘণ্টা ঢালার আগে তিনটি জিনিস দেখে নিন।

প্রথমত, কতগুলো ছবি নথিভুক্ত হলো। mapper সেটি জানায়। ৬০০ ফ্রেম দিয়ে যদি ৩৪০টি নথিভুক্ত হয়, তবে আপনি যে ধারণটি হাতে আছে ভাবছেন সেটি আসলে নেই — আর বাদ পড়া ২৬০টি সাধারণত পরপর থাকে; ঠিক সেখানেই ঘরের ভেতর কিছু একটা গড়বড় হয়েছিল।

দ্বিতীয়ত, কয়টি মডেল বেরোলো। একটির বেশি মানে দৃশ্যটি জোড়া লাগেনি।

তৃতীয়ত, বিন্দুমেঘটি চোখে দেখুন। নিয়মরক্ষার জন্য নয়: খুলে দেখুন আকৃতিটি গাছের মতো লাগছে কি না। ভাঁজ খাওয়া বা দ্বিগুণ হয়ে যাওয়া পুনর্গঠন তিন সেকেন্ড তাকালেই ধরা পড়ে, আর লগ-এ কখনোই ধরা পড়ে না।

দুটি ব্যবহারিক টুকিটাকি

বিল্ড গুরুত্বপূর্ণ। আপনার ডিস্ট্রিবিউশনের প্যাকেজ ম্যানেজারের COLMAP হয়তো CUDA ছাড়াই কম্পাইল করা, আর তখন উপরের GPU ফ্ল্যাগগুলো হয় কিছুই করে না, নয়তো সরাসরি ব্যর্থ হয়। এ কারণেই আমি সিস্টেমেরটার পাশাপাশি একটি CUDA-সক্ষম বিল্ড আলাদা করে রাখি।

আর হেডলেস মেশিনে COLMAP একটি OpenGL কনটেক্সট বানাতে গিয়ে ক্র্যাশ করবে। export QT_QPA_PLATFORM=offscreen দিলে ঠিক হয়ে যায়। একবার এতে আমার একটি বিকেল গেছে, আর এররটি এমন কোথাও ইশারা করে না যা কাজে লাগে।

শেষে হাতে যা থাকে

নথিভুক্ত প্রতিটি ছবির ক্যামেরা-অবস্থান, একটি বিন্দুমেঘ, আর বিকৃতিমুক্ত ছবি — স্প্ল্যাট অপ্টিমাইজার শুরু করতে যা যা লাগে, সব।

যা থাকে না তা হলো গাছটি ঠিক কত বড়, তার কোনো ধারণা। COLMAP জ্যামিতির ব্যাপারে সূক্ষ্মদর্শী আর স্কেলের ব্যাপারে নীরব — কারণটি আগের লেখাতেই বলা: এই পুরো প্রক্রিয়ার কোথাও কোনো ছবিকে কোনো স্কেলের সঙ্গে মেলানো হয়নি।


পরের পর্বে মূল ধারাবাহিকে ফিরছি: স্কেল একবারও ঠিক না করে গাছের বৈশিষ্ট্য মাপা যায় কীভাবে।