การตรวจหาผิวหนัง hsb พื้นฐาน, ไฟนีออน


14

ฉันหวังว่านี่คือสถานที่ที่เหมาะสมที่จะถาม ยังไงก็ขอโทษสำหรับความผิดพลาดของฉันและ pleace แนะนำเว็บไซต์ที่ดีกว่า

ฉันกำลังพยายามใช้เครื่องตรวจจับผิวหนังที่เรียบง่ายเป็นพิเศษโดยใช้อิมเมจ hsb บางช่วง ผมใช้วิธีการอธิบายที่นี่และที่นี่

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

ทำไม?

ฉันใช้อัลกอริทึมที่อธิบายไว้ในแหล่งที่สอง :

  1. แปลงภาพพื้นที่สี HSV โฮ
  2. ใส่สีขาวในช่วง 0 <H <38
  3. ขยายตัวกรอง
  4. ตัวกรองกร่อน
  5. ตัวกรองเบลอ

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบ:


10

สิ่งนี้จริงอาจทำงานได้ดีขึ้นโดยใช้แบบจำลอง generative ใน RGB แทน HSV

  1. รับภาพการฝึกอบรมหรือภาพการฝึกอบรมที่มีผิวหนัง
  2. เลือกพิกเซลสกินด้วยตนเอง (เช่นโดยการสร้างมาสก์ไบนารี)
  3. คำนวณค่าเฉลี่ยและความแปรปรวนร่วมของโทนสีผิวใน RGB (แต่ละค่าควรเป็นเวกเตอร์องค์ประกอบ 3 ส่วน)
  4. สำหรับพิกเซลที่ไม่รู้จักคำนวณระยะทาง Mahalanobis จากค่าเฉลี่ยโดยใช้ความแปรปรวนร่วม
  5. จัดประเภทเป็นสกินถ้าระยะทางน้อยกว่าขีด จำกัด
  6. ปรับเกณฑ์เพื่อประสิทธิภาพที่ดีที่สุด

nnPม.ม.ม.PQQ=Q'Q คือ 3 x 3

แก้ไข 2: ค่าที่คุณได้รับดูเหมือนจะใหญ่เกินไป ในการรับค่าความแปรปรวนร่วมสูงสุดให้สร้างเมทริกซ์ต่อไปนี้:

255 255 255
 0   0   0

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


ฉันมีปัญหาในการทำความเข้าใจวิธีรับเมทริกซ์ความแปรปรวนร่วม 3x3 กับ opencv จากภาพ .. คุณช่วยให้ฉันอ้างอิงได้ไหม?
nkint

@nkint โปรดดูคำตอบที่แก้ไขแล้ว
Dima

เยี่ยมมาก ใน 5 บรรทัดคุณทำให้ฉันเข้าใจว่าความแปรปรวนร่วมคืออะไร ขอบคุณ มันได้ผล. แต่ฉันมีปัญหาในการเก็บผลลัพธ์ ถ้าฉันมีพิกเซลตั้งแต่ 0-255 ฉันควรคาดหวังจำนวนใดของระยะทาง Mahalanobis ถ้าฉันเก็บไว้ใน 8-uint มันใช้เวลาเพียงส่วนเล็ก ๆ ของผิวหนังถ้าฉันเก็บไว้ใน 32- ลอยฉันได้เสียง
แปลก

ใช่ฉันคิดว่าฉันกำลังทำอะไรผิดเพราะเมทริกซ์ความแปรปรวนร่วมของฉันคือ: [10913058.00000000, 7046611.50000000, 3290781.50000000; 7046611.50000000, 4811646.00000000, 2225078.00000000; 3290781.50000000, 2225078.00000000, 1387631.87500000]
nkint

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

4

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

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

ขั้นตอนวิธีการอื่นที่เกี่ยวข้องกับการตรวจสอบผิว แต่ไม่เกี่ยวข้องมากเกินไปที่จะให้แสงไฟนีออนเป็นคนนี้


2

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

OpenCV แทน HSV แตกต่างจากแหล่งอื่น ๆ ที่คุณอาจพบ:

  • ความแตกต่างที่ใหญ่ที่สุดสำหรับคุณคือ w / r / t สีสัน: OpenCV หมายถึงสีตั้งแต่ 0 ถึง 179 เมื่อเกือบทุกอย่างใช้ประโยชน์จากบิตที่แขวนเพื่อเก็บข้อมูลเพิ่มเติม w / 0-255
  • ข้อแตกต่างอื่น ๆ : การวัดความอิ่มตัวจะกลับด้านเมื่อเปรียบเทียบกับบรรทัดฐาน ดังนั้นความอิ่มตัว 255 หมายถึงความสว่างใน opencv แทนที่จะเป็นสีขาว (แจ้งให้ทราบล่วงหน้าเรากลับไปที่ 255 - เฉพาะเฉดสีคือ 0-180 อาจเป็นเพราะตัวแทน 'ล้อ')

อาจจะสายเกินไปที่จะช่วยคุณ แต่มันเป็นคำถามที่น่าสนใจและบางคนอาจพบปัญหาเดียวกัน


-1
import sys
import numpy
import cv2

cap = cv2.VideoCapture(0)
while(1):
    _, im = cap.read()

    im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2YCR_CB)

    skin_ycrcb_mint = numpy.array((0, 133, 77))
    skin_ycrcb_maxt = numpy.array((255, 173, 127))
    skin_ycrcb = cv2.inRange(im_ycrcb, skin_ycrcb_mint, skin_ycrcb_maxt)

    cv2.imshow("Second Image", skin_ycrcb) # Second image
    contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, 
        cv2.CHAIN_APPROX_SIMPLE)
    for i, c in enumerate(contours):
        area = cv2.contourArea(c)
            if area > 1000:
                cv2.drawContours(im, contours, i, (255, 0, 0), 3)
    cv2.imshow("Final Image", im)         # Final image
    cv2.waitKey(1)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.