tewson's thoughtstream

ห้วงหนึ่งของความเกรียน

Primary links

  • home
  • films
  • free software
  • about

Recent Posts

  • ความบิดเบือนจากสำนวนแปลบางข่าวของมติชน
  • ใครบอกว่าอะไรที่ปรากฏอยู่บนอินเทอร์เน็ตแล้วจะไม่หายไป
  • การ retweet อย่างฉลาด (ถ้าจะ retweet คุยกันให้ได้น่ะนะ!)
  • เสียงรบกวนจากงานเลี้ยงในมหาวิทยาลัยธรรมศาสตร์ รังสิต
  • ทำดีได้ดีมีที่ไหน ทำชั่วได้ดีมีถมไป

Tags in Tags

announcement bacc bangkok film lecture life poetry tcdc tech thought travel university
more tags

Stay Tuned

Subscribe

Faulty Barcode Detection

Submitted by tewson on Sat, 19/09/2009 - 18:43
  • image processing
  • intellect
  • programming
  • project
  • tech

อันนี้เป็นโครงงานเล็ก ๆ จากวิชา Computer Vision หัวข้อคือ ทำไงก็ได้ให้คอมมันรู้ได้ว่าภาพบาร์โค้ดมันสกปรก มีภาพตัวอย่างมาให้ด้วย

Barcode1

Barcode2

Barcode3

ดูแล้วก็แบบ เอ่อ มันสกปรกตรงไหนเนี่ย แต่ก็นั่นล่ะ เจ้าของโจทย์จริง ๆ เป็นบริษัทที่พิมพ์พวกบรรจุภัณฑ์กระดาษ เลยต้องการวิธีตรวจคุณภาพการพิมพ์ที่มันอัตโนมัติ (จริง ๆ แล้วซอฟท์แวร์อ่านบาร์โค้ดสมัยนี้มันฉลาดมาก เบี้ยวก็อ่านได้ เบลอก็อ่านได้)

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

เลือกข้อบาร์โค้ดนี่เพราะว่าข้อแรกคนทำเยอะมาก (เพราะเห็นผลชัดเจน) ตัวเปรียบเทียบเยอะ (ฮา) ส่วนข้อที่สองนี่ก็มีสูตรคณิตศาสตร์อยู่แล้ว เลือกข้อสุดท้ายนี่แหละ ท่าจะมันส์

เอาเข้าจริงมันก็มันส์ไปหน่อย งานวิชาอื่นก็ดันมาส่งพร้อม ๆ กัน (บอกผมสิว่าคุณไม่ดองงาน) ไอเดียในการแก้ปัญหามันเลยแอบเผา แต่อย่างน้อยมันก็ทำงานได้ตามจุดประสงค์เท่าที่มีตัวอย่างน่ะนะ

ข้อความข้างล่างนี้ไปอาจจะน่าเบื่อไปหน่อย จริง ๆ ข้ามไปดูวิดีโอข้างล่างสุดได้เลย เอ๊ะ แต่ก็อยากให้อ่านแฮะ

ไอเดียคร่าว ๆ ก็คือใช้ความ "เส้นเยอะ" (ไม่ใช่เส้นใหญ่) ของบาร์โค้ด ตอนแรกก็จับภาพนั้นมาหาเส้นก่อน ด้วย Hough transform (แปลไทยว่า "การแปลงฮัฟ" เท่สลัด ๆ) จะได้เส้นเยอะ ๆ ออกมา ซึ่งเส้นส่วนมากที่ได้จะมาจากบาร์โค้ด จากนั้นก็ดูมุมของความชันของเส้นพวกนั้น จัดการแบ่งมุมที่พบออกเป็นกลุ่มย่อย ๆ ก็จะพบว่ามีช่วงของขนาดมุมหนึ่ง ๆ ที่มีจำนวนเยอะกว่าช่วงอื่น (เช่น ถ้าบาร์โค้ดมันเอียงอยู่ประมาณ 45 องศา เราก็จะพบเส้นที่มีมุม 45 องศาเยอะกว่าเส้นที่ตั้งตรง) เราก็ถือเอาว่าช่วงมุมนั้นล่ะ เป็นมุมของความเอียงของบาร์โค้ด แล้วก็หมุนภาพให้บาร์โค้ดมันตั้งตรงซะ

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

ต่อมาขอบแนวนอนนี่ปัญหาเลย เพราะบาร์โค้ดมันไม่มีขอบแนวนอน จะหารูปแบบของเส้นที่มันไม่ค่อยปะติดปะต่อกันแบบนั้นก็คงจะยากไป เลยจัดการ "ขยาย" (Dilate) แต่ละแท่งในบาร์โค้ดนั้นตามแนวนอน มันก็จะมาเชื่อมกัน กลายเป็นกล่อง มีขอบแนวนอนแล้ว เย้ (จริง ๆ ก็ขยายออกทางข้างแม่งทั้งภาพนั่นแหละ เพียงแต่ขยายนิดเดียว ส่วนอื่นของภาพไม่มีผลกระทบมาก แต่ช่องว่างในบาร์โค้ดมันแคบ เลยเชื่อมกันได้)

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

เมื่อตัดเอาบาร์โค้ดออกมาได้แล้ว จะหารอยเปื้อนได้ยังไง คิดอยู่พักใหญ่เลย จะหาขอบของรอยเปื้อน จุดมันก็เล็กเกินไป ปกติในการหาความแตกต่างของภาพสองภาพ วิธีเบื้องต้นสุด ๆ คือการเอาสองภาพนั้นมาลบกัน (ลองนึกตามว่ามีภาพ (1) จุดสามจุด กับภาพ (2) จุดเดียวตรงกลาง เอาภาพ (2) ลบออกจากภาพ (1) ก็น่าจะได้จุดข้าง ๆ ที่เหลือ) ทีนี้ ถ้าเรามีภาพบาร์โค้ดเปื้อน ๆ อยู่ จะเอาภาพบาร์โค้ดสะอาด ๆ ที่ไหนมาลบออกไปล่ะ จ้องไปจ้องมาพบว่า เฮ้ย เราตั้งบาร์โค้ดได้แล้ว ถ้าเรา "หด" (Erode) ภาพบาร์โค้ดเปื้อนนั้นตามแนวตั้งเนี่ย พวกจุดก็จะหายไป แต่เส้นยังอยู่ (เพราะเส้นแนวตั้งมันยาว หดไปบ้างแต่ไม่หายไป) แล้วขยายกลับคืนตามแนวตั้ง ก็จะได้ภาพบาร์โค้ดสะอาด ๆ มา เอาไปลบออกจากภาพเดิมที่เปื้อนอยู่ ก็จะได้รอยเปื้อน!

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

มันน่าสับสนสินะ ใครที่อ่านข้างบนมานี่แล้วเข้าใจทั้งหมดผมแม่งโคตรนับถือเลยอะ ผมแนบวิดีโอสาธิตมาด้วยข้างล่างนี้ มีให้เห็นแต่ละขั้นตอนด้วย

เท่านั้นไม่พอ มีรายงาน (pdf ประมาณ 7 เม็กฯ) กับโค้ดกาก ๆ (เขียนด้วย Python ใช้ไลบรารี่ OpenCV) ให้เอาไปหัวเราะเยาะด้วยเอ้า (อยากจะหาเวลาศึกษาการเขียนโค้ดแบบ Pythonic อยู่ครับ ไอ้แบบ tewsonic ที่เขียนนี่มันอนาถสิ้นดี)

แล้วก็ ผมเชื่อว่ามีวิธีที่ฉลาดกว่านี้อยู่มากมาย ใครเห็นใจก็บอกกันหน่อยนะจ๊ะ

เจ๊งมาก

Submitted by tspp (not verified) on Sat, 19/09/2009 - 18:53.

เจ๊งมาก หลายอันเรายังคิดไม่ถึงเลย

แหล่มสุดๆ

  • reply

เฮ้ย ยังไม่เจ๊ง

Submitted by tewson on Sat, 19/09/2009 - 19:39.

เฮ้ย ยังไม่เจ๊ง

  • reply

เยี่ยมครับ อนาคตนักวิจัย

Submitted by Sucha (not verified) on Sat, 19/09/2009 - 19:30.

เยี่ยมครับ อนาคตนักวิจัย อิอิ

  • reply

เอ้ย สระผิดตัวนึง 55555

Submitted by tspp (not verified) on Sat, 19/09/2009 - 21:37.

เอ้ย สระผิดตัวนึง 55555

  • reply

เจ๋งๆ เมพมากๆ

Submitted by xphp (not verified) on Sun, 04/10/2009 - 11:50.

เจ๋งๆ เมพมากๆ

  • reply

เป็นวิธีที่เจ๋งดีครับ ผมลองคิ

Submitted by nattster (not verified) on Tue, 06/10/2009 - 02:10.

เป็นวิธีที่เจ๋งดีครับ

ผมลองคิดเล่นๆ อีกวิธี

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

คำนวณว่า "zone ที่อ่านออก(ได้รหัสถูกต้อง) คิดเป็นกี่ % ของ barcode ทั้งหมด"

--> แต่แบบนี้มันก็ไม่ใช่โปรเจค computer vision สินะ

มั่วๆ ครับ

  • reply

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

Recent comments

  • เห็นด้วยอย่างยิ่งครับ ผมเจออย
    1 week 2 days ago
  • good observation! BTW, even
    1 week 5 days ago
  • ตรงนอกเรื่องบรรทัดสุดท้ายนั่น
    1 week 5 days ago
  • นสพ.ไทยเคยแปลข่าวถูกด้วยเหรอ
    1 week 6 days ago
  • Thanks for this. I spent 2
    1 week 6 days ago
more
Powered by Drupal, an open source content management system

Creative Commons License

This work by http://tewson.com is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
RoopleTheme