สารบัญ:

Eyeballing Your Eyeball's Prescription: โครงการ BME60B: 9 ขั้นตอน
Eyeballing Your Eyeball's Prescription: โครงการ BME60B: 9 ขั้นตอน

วีดีโอ: Eyeballing Your Eyeball's Prescription: โครงการ BME60B: 9 ขั้นตอน

วีดีโอ: Eyeballing Your Eyeball's Prescription: โครงการ BME60B: 9 ขั้นตอน
วีดีโอ: Ask Me Anything - 2022 Edition 2024, กรกฎาคม
Anonim
Eyeballing Your Eyeball's Prescription: โครงการ BME60B
Eyeballing Your Eyeball's Prescription: โครงการ BME60B

โดย: Hannah Silos, Sang Hee Kim, Thomas Vazquez, Patrick Viste

การขยายภาพเป็นหนึ่งในคุณสมบัติหลักสำหรับแว่นอ่านหนังสือ ซึ่งจำแนกตามใบสั่งยาไดออปเตอร์ ตามที่มหาวิทยาลัยเทคโนโลยีมิชิแกน ไดออปเตอร์คือความยาวโฟกัสของเลนส์ ซึ่งมักจะวัดเป็นมม. ในหน่วยเมตร (มหาวิทยาลัยเทคโนโลยีมิชิแกน) เนื่องจากแว่นอ่านหนังสือมีเลนส์นูน ทางยาวโฟกัสจะเป็นบวก ทำให้ไดออปเตอร์เป็นบวกด้วย (HyperPhysics) ทางยาวโฟกัสจะเพิ่มขึ้นเมื่อระยะห่างระหว่างวัตถุอยู่ห่างจากเลนส์จริงมากขึ้น และทำให้ไดออปเตอร์ลดลงเนื่องจากเป็นสัดส่วนผกผัน ดังนั้นการมีแว่นอ่านหนังสือที่มีไดออปเตอร์เพิ่มเติมจะช่วยให้เลนส์ซูมภาพได้จนดูเหมือนทางยาวโฟกัสจะน้อยลงโดยการเพิ่มค่าของไดออปเตอร์

รหัสที่นำเสนอจะใช้ทำนายไดออปเตอร์ของเลนส์โดยไม่ทราบค่าสายตา มีการใช้อินพุต 2 ตัวในการคำนวณใบสั่งยา: ภาพถ่ายพื้นหลังควบคุมโดยไม่ต้องใช้เลนส์ และภาพถ่ายอื่นที่มีพื้นหลังเดียวกันแต่ผ่านเลนส์ที่เลือก โปรแกรมจะวัดความบิดเบี้ยวระหว่างสองภาพนี้ จากนั้น เราจะสามารถประมาณค่าไดออปเตอร์ของเลนส์และสร้างผลลัพธ์ให้ผู้ใช้ดูได้

สำหรับคำแนะนำนี้ คุณจะต้อง:

  • รูปแบบกระดานหมากรุกขาวดำพิมพ์บนกระดาษขนาด 11x8.5 นิ้ว
  • กล้องที่มีความสามารถในการล็อคโฟกัส
  • ขาตั้งกล้องหรือสิ่งของที่คล้ายกันเพื่อยึดกล้อง
  • แว่นอ่านหนังสือต่างๆ
  • MATLAB

ขั้นตอนที่ 1: ถ่ายภาพ

ถ่ายภาพ
ถ่ายภาพ
ถ่ายภาพ
ถ่ายภาพ
ถ่ายภาพ
ถ่ายภาพ

ในการคำนวณกำลังขยายของเลนส์ คุณต้องสามารถเปรียบเทียบกับขนาดจริงของวัตถุได้ สำหรับโครงการนี้ เราจะเปรียบเทียบภาพที่ขยายแล้วกับภาพควบคุม

ดังนั้น ขั้นตอนแรกคือการถ่ายภาพสองภาพที่มีภาพเดียวกัน - ภาพแรกผ่านกล้องเพียงอย่างเดียว และภาพที่สองผ่านเลนส์ของแว่นอ่านหนังสือที่คุณต้องการทดสอบ

คุณจะถ่ายภาพกระดานหมากรุกขาวดำขนาด 8.5x11 นิ้วพร้อมตารางขนาด 1 นิ้ว ตั้งค่ากล้องของคุณให้ห่างจากกระดานหมากรุก 11 นิ้ว ก่อนถ่ายภาพ ควรล็อกโฟกัสบนกระดานหมากรุก

ถ่ายรูปกระดานหมากรุกโดยไม่สวมแว่นอ่านหนังสือ จากนั้นวางแว่นอ่านหนังสือไว้หน้ากล้องและถ่ายภาพที่สองโดยไม่ขยับอะไรเลย

ตรวจสอบให้แน่ใจว่าตำแหน่งของกล้องของคุณไม่เคลื่อนไปมาระหว่างภาพ สิ่งเดียวที่ควรเปลี่ยนระหว่างสองภาพคือการมีเลนส์แว่นตาอยู่ด้านหน้ากล้อง

เมื่อคุณถ่ายภาพเสร็จแล้ว ให้อัปโหลดไปยังคอมพิวเตอร์ของคุณ

ขั้นตอนที่ 2: โหลดรูปภาพลงใน MATLAB

โหลดรูปภาพลงใน MATLAB
โหลดรูปภาพลงใน MATLAB

เปิดสคริปต์ใหม่

ขั้นแรก ระบุไดเร็กทอรีที่เก็บรูปภาพ จากนั้น ใช้ฟังก์ชัน dir เพื่อแยกรูปภาพ-j.webp

Dir = 'C:\Users\kuras\Desktop\classes\SQ2\BME60b\Sandbox\testphotos'; GetDir = dir('*.jpg');

สำหรับโครงการของเรา เราต้องการแจ้งให้ผู้ใช้โปรแกรมทราบว่าต้องการเปรียบเทียบไฟล์ใด ส่วนแรกขอให้ผู้ใช้ระบุภาพควบคุม และส่วนที่สองขอให้ผู้ใช้ระบุภาพทดสอบ

  • %ถามผู้ใช้ว่าไฟล์ใดเป็นภาพควบคุม
  • Control = input('# ของภาพควบคุม\n');
  • ControlFile = [GetDir (ควบคุม) ชื่อ]
  • ถามผู้ใช้ว่าไฟล์ใดเป็นภาพที่พวกเขาต้องการวิเคราะห์
  • SelectFile = input('\n# ของรูปภาพที่คุณต้องการวิเคราะห์\n');
  • PrescripFile = [GetDir (เลือกไฟล์).name];

ขั้นตอนที่ 3: การวิเคราะห์ภาพ

การวิเคราะห์ภาพ
การวิเคราะห์ภาพ
การวิเคราะห์ภาพ
การวิเคราะห์ภาพ

ภาพสีใน MATLAB มีขนาด MxNx3 ในขณะที่ภาพระดับสีเทาคือ MxN ซึ่งหมายความว่าการปรับปรุง/แก้ไขภาพระดับสีเทาทำได้เร็วกว่าเนื่องจากมีข้อมูลให้ติดตามน้อยกว่า ใช้ rgb2gray เพื่อแปลงภาพเป็นระดับสีเทา (มีการใช้ฟังก์ชัน imrotate เนื่องจากรูปภาพของเราอยู่ในแนวนอน - โค้ดบรรทัดนี้อาจจำเป็นหรือไม่จำเป็นในเวอร์ชันของคุณ)

  • % แปลงเป็นระดับสีเทาแล้วหมุน
  • ฉัน = imread(ControlFile);
  • ผม = rgb2gray(I);
  • ฉัน = imrotate(I, 90);

ถัดไป ให้แสดงภาพ ใช้ฟังก์ชันแผนย่อยเพื่อให้ภาพทดสอบสามารถอยู่ถัดจากตัวควบคุมได้ในขั้นตอนต่อๆ ไป

  • %แสดง
  • รูปที่ 1);
  • โครงเรื่องย่อย(1, 2, 1)
  • อิมโชว์(I);
  • ชื่อเรื่อง (ControlFile);

ใช้ความไม่คร่อมเพื่อให้ผู้ใช้ครอบตัดกระดานหมากรุกออกจากภาพเต็ม รหัสต่อไปนี้ยังแสดงกล่องข้อความเพื่อให้คำแนะนำแก่ผู้ใช้

  • % ครอบตัดกระดานหมากรุกเพื่อการวิเคราะห์
  • waitfor(msgbox({'Use the cross hairs to crop out checkerboard.', 'จากนั้นดับเบิลคลิกที่พื้นที่ที่สนใจ'}));
  • I_crop = ไม่ครอบตัด (I);

ใช้ imbinarize เพื่อทำให้ภาพเป็นไบนารี

I_binary = imbinarize (I_crop);

ขั้นตอนที่ 4: คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก

คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก
คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก
คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก
คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก
คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก
คำนวณความกว้างของสี่เหลี่ยมสีขาวบนกระดานหมากรุก

ถัดไป ให้ผู้ใช้ลากเส้นข้ามรูปภาพโดยใช้ imline เส้นนี้ควรวิ่งในแนวนอนบนกระดานหมากรุก ควรเริ่มต้นและสิ้นสุดด้วยสี่เหลี่ยมสีดำ (ไม่ว่าที่ใด) เนื่องจากเราจะวัดความกว้างของสี่เหลี่ยมสีขาว ไม่ใช่สี่เหลี่ยมสีดำ

  • %วาดเส้น
  • รูปที่ 1)
  • โครงเรื่องย่อย(1, 2, 1)
  • imshow(I_binary);
  • waitfor(msgbox({'คลิกและลากเพื่อวาดเส้นที่มีความยาว 9 ช่อง จากพื้นที่สีดำไปยังพื้นที่สีดำ', 'ดับเบิลคลิกเพื่อยืนยัน'}));
  • เส้น = imline;
  • ตำแหน่ง = รอ (สาย);
  • จุดปลาย = line.getPosition;

แยกพิกัด X และ Y สำหรับจุดสิ้นสุดของเส้นที่ลาก

  • X = จุดสิ้นสุด (:, 1)
  • Y = จุดสิ้นสุด (:, 2);

ใช้ improfile เพื่อสร้างกราฟตามความเข้มที่พบในเส้นที่ลาก สิ่งนี้ควรคล้ายกับคลื่นสี่เหลี่ยมตั้งแต่ 0 (สีดำ) ถึง 1 (สีขาว) คำนวณยอดเขาและตำแหน่งของมันด้วย

  • รูป (2)
  • โครงเรื่องย่อย(1, 2, 1)
  • title('ความเข้มของภาพในบรรทัด improfile (การควบคุม)')
  • improfile(I_binary, X, Y); กริดบน;
  • [~, ~, c1, ~, ~] = improfile(I_binary, X, Y);
  • [พีค, loc] = findpeaks(c1(:,:, 1));
  • เดี๋ยว
  • พล็อต (loc, peaks, 'ro');
  • ออกจาก

ค้นหาความยาวของที่ราบสูงแต่ละอันบนกราฟ improfile โดยใช้ for loop เรียกใช้ for ลูปสำหรับจำนวนพีคเท่ากันในกราฟอิมโพรไฟล์ ในการคำนวณความยาวของที่ราบสูงแต่ละแห่ง ให้ใช้ฟังก์ชัน "ค้นหา" เพื่อค้นหาตำแหน่งทั้งหมดที่มี "1" แทนที่จะเป็นค่าความเข้ม "0" จากนั้น คำนวณความยาวของอาร์เรย์นั้นเพื่อรับความยาวรวมของที่ราบสูง ซึ่งควรเท่ากับความกว้างของสี่เหลี่ยมสีขาวในหน่วยพิกเซลControlPlateauList = zeros(1, length(loc));

สำหรับฉัน = 1: ความยาว (loc)

ถ้าฉัน == ความยาว (loc)

ที่ราบสูง = ค้นหา(c1(loc(i):end,:, 1));

อื่น

ที่ราบสูง = ค้นหา(c1(loc(i):loc(i+1)-1,:, 1));

จบ

ControlPlateauList(i) = ความยาว(ที่ราบสูง);

จบ

ขั้นตอนที่ 5: ทำซ้ำขั้นตอนที่ 3 และ 4 สำหรับภาพทดสอบ

ทำซ้ำขั้นตอนที่ 3 และ 4 สำหรับภาพทดสอบ
ทำซ้ำขั้นตอนที่ 3 และ 4 สำหรับภาพทดสอบ

*หมายเหตุ: เมื่อวาดเส้น improfile บนรูปภาพทดสอบ ตรวจสอบให้แน่ใจว่าได้วาดข้ามช่องสี่เหลี่ยมที่สอดคล้องกับเส้นที่คุณวาดบนรูปภาพควบคุม

ขั้นตอนที่ 6: คำนวณกำลังขยายของเลนส์

คำนวณกำลังขยายของเลนส์
คำนวณกำลังขยายของเลนส์

การวัดแบบขยายคำนวณโดยการหารค่าเฉลี่ยของความยาวของที่ราบสูง ซึ่งคำนวณในขั้นตอนที่ 5 ด้วยค่าเฉลี่ยของความยาวของที่ราบสูงควบคุม ซึ่งคำนวณได้ในขั้นตอนที่ 4 ซึ่งคำนวณได้เป็น 1.0884

กำลังขยาย = ค่าเฉลี่ย (plateauList)/mean (ControlPlateauList);

ขั้นตอนที่ 7: ค้นหา R-squared และใบสั่งยาของผู้ใช้ผ่าน Interpolation

การค้นหา R-squared และข้อกำหนดของผู้ใช้ผ่าน Interpolation
การค้นหา R-squared และข้อกำหนดของผู้ใช้ผ่าน Interpolation

ใช้รหัส:

  • md1 = fitlm(GivenPrescription, MagArray);
  • Rsquared = md1. Rsquared. Ordinary;

เราสามารถหาค่า R-squared ของกราฟ GivenPresciption (เลนส์ของเราได้รับค่า) เทียบกับ MagArray (อาร์เรย์ของอัตราส่วนการวัดกำลังขยายที่เราคำนวณไว้ก่อนหน้านี้) โดยการมีค่า R-squared ที่สูงเพียงพอ สามารถอนุมานได้ว่ามีความสัมพันธ์ที่ดีพอที่จะพิสูจน์การใช้วิธีนี้ สำหรับกรณีนี้โดยเฉพาะ ค่า R-squared คือ 0.9912 ซึ่งแสดงให้เห็นความสัมพันธ์ที่แข็งแกร่งและดังนั้นจึงมีเหตุผลในการใช้วิธีนี้ในการวิเคราะห์

การใช้ฟังก์ชัน:

ใบสั่งยา = interp1 (MagArray, GivenPrescription, กำลังขยาย, 'เชิงเส้น');

เราสามารถสอดแทรกค่าใบสั่งยาที่สอดคล้องกัน (บนแกน x) ของอัตราส่วนกำลังขยายของเรา (ค่าบนแกน y) และค้นหาใบสั่งยาของผู้ใช้

การสอดแทรกข้อมูลเป็นสิ่งสำคัญสำหรับวิธีนี้ในการทำงาน เนื่องจากช่วยให้เราสามารถตั้งสมมติฐานเกี่ยวกับข้อมูลที่เราไม่มีได้ โดยอิงจากข้อมูลที่เรามี แม้ว่าในทางเทคนิคแล้ว เส้นที่เหมาะสมที่สุดจะเป็นตัวเลือกที่แข็งแกร่งกว่าสำหรับสมมติฐานนี้ แต่การสร้างขอบเขตเพื่อลดจำนวนเอาต์พุตก็ให้ผลเช่นเดียวกัน เนื่องจากแว่นสายตามีค่าสม่ำเสมอเพิ่มขึ้นอยู่ดี ซึ่งจะอธิบายในขั้นตอนต่อไป

ขั้นตอนที่ 8: แสดงการกําหนดของผู้ใช้บนกราฟ

การแสดงใบสั่งยาของผู้ใช้บนกราฟ
การแสดงใบสั่งยาของผู้ใช้บนกราฟ

โดยใช้รหัสต่อไปนี้:

  • รูป;
  • พล็อต (GivenPrescription, MagArray, '-g')
  • เดี๋ยว
  • พล็อต(ใบสั่งยา, กำลังขยาย, 'bp')
  • ออกจาก
  • กริด
  • ตำนาน ('ข้อมูล', 'จุดแทรก', 'ตำแหน่ง', 'NW')

เราสามารถพล็อตกราฟที่แสดงอัตราส่วนกำลังขยายเทียบกับข้อกำหนดที่กำหนดด้วยเส้นสีเขียวและข้อมูลที่พบของการขยายที่คำนวณได้เทียบกับค่าใบสั่งยาที่สอดแทรกด้วยดาวสีน้ำเงิน จากนั้นตำนานจะติดป้ายกำกับชื่อ แกน x และแกน y แล้ววางคำอธิบายไว้ที่มุมบนซ้าย

ขั้นตอนที่ 9: จำกัดใบสั่งยาของคุณให้แคบลง

จำกัดใบสั่งยาของคุณให้แคบลง
จำกัดใบสั่งยาของคุณให้แคบลง

รหัสต่อไปนี้ใช้ในการผลิตการปัดเศษสำหรับใบสั่งยา:

  • ถ้าใบสั่งยา <= 1.125

    CalculatedPrescription = '1.0';

  • ใบสั่งยา elseif <= 1.375

    CalculatedPrescription = '1.25';

  • ใบสั่งยา elseif <= 1.625

    CalculatedPrescription = '1.5';

  • ใบสั่งยา elseif <= 1.875

    CalculatedPrescription = '1.75';

  • ใบสั่งยา elseif <= 2.25

    CalculatedPrescription = '2.0';

  • ใบสั่งยา elseif <= 2.625

    CalculatedPrescription = '2.5';

  • ใบสั่งยา elseif <= 3

    CalculatedPrescription = '2.75';

  • ใบสั่งยา elseif <= 3.375

    CalculatedPrescription = '3.25';

  • อื่น

    CalculatedPrescription = 'ไม่ทราบ';

  • จบ

ใบสั่งยาที่พบในการแก้ไขไม่จำเป็นต้องสะท้อนถึงใบสั่งยาจริง เนื่องจากการวิเคราะห์ภาพถ่ายจะมีความแตกต่างกันเล็กน้อยเนื่องจากความผิดพลาดของมนุษย์ ดังนั้น เราต้องการขั้นตอนนี้เพื่อจำแนกใบสั่งยาที่แท้จริง

ใบสั่งยาที่ให้มักจะเริ่มต้นจาก 1.0 diopters และเพิ่มขึ้น.25 ในใบสั่งยา ดังนั้นหลังจากคำนวณใบสั่งยาแล้ว เราต้องการที่จะกำหนดใบสั่งยาที่เหมาะสมกับสิ่งที่ผู้ใช้อาจต้องการมากที่สุด หลังจากคำนวณใบสั่งยาแล้ว เราจะเรียกใช้คำสั่ง if เพื่อตรวจสอบค่าและกำหนดว่าใบสั่งยาใดที่จำเป็น ค่าใดก็ตามที่น้อยกว่าหรือเท่ากับ 1.125 ใบสั่งยาคือ 1.0 ค่าใดก็ตามที่น้อยกว่าหรือเท่ากับ 1.375 ใบสั่งยาคือ 1.25 ค่าใดก็ตามที่น้อยกว่าหรือเท่ากับ 1.625 ใบสั่งยาคือ 1.5 ค่าใดก็ตามที่น้อยกว่าหรือเท่ากับ 1.845 ใบสั่งยาคือ 1.75 และอื่นๆ.

เรามีค่าเพิ่มขึ้นเนื่องจากเรากำลังตรวจสอบว่าค่าน้อยกว่าหรือไม่ หากเราทำค่าที่ลดลงแล้วคำสั่ง if จะอ่านคำสั่งแรกตลอดเวลา ถ้าใบสั่งยามีค่าน้อยที่สุด เราต้องการให้ยารับรู้ว่าค่ายานั้นน้อยที่สุดในทันที ดังนั้นนั่นคือสาเหตุที่ค่าที่น้อยที่สุดคือสิ่งที่เราเริ่มด้วย ค่าใดก็ตามที่สูงกว่าค่าสูงสุดหมายความว่าใบสั่งยาไม่อยู่ในช่วงของข้อมูลของเรา ดังนั้นจะให้การอ่านสตริง "ไม่ทราบ"

แนะนำ: