ที่อื่นในหัวข้อนี้ user1149913 ให้คำแนะนำที่ดี (กำหนดตัวแบบความน่าจะเป็น) และโค้ดสำหรับแนวทางที่มีประสิทธิภาพ (การประมาณค่า EM) ยังคงมีสองประเด็นที่ต้องแก้ไข:
วิธีรับมือกับการออกจากแบบจำลองความน่าจะเป็น (ซึ่งเห็นได้ชัดมากในข้อมูล 2011-2012 และค่อนข้างชัดเจนในการแยกแยะของจุดที่มีความลาดชันน้อยกว่า)
วิธีระบุค่าเริ่มต้นที่ดีสำหรับอัลกอริทึม EM (หรืออัลกอริทึมอื่น ๆ )
ไปยังที่อยู่ที่ 2 พิจารณาการใช้Hough เปลี่ยน นี่คือขั้นตอนวิธีการตรวจสอบคุณลักษณะซึ่งสำหรับการค้นหาเหยียดเชิงเส้นของคุณสมบัติได้มีการคำนวณเป็นเรดอนเปลี่ยน
xYx , yในการแปลง Hough เมื่อคุณสมบัติในพล็อตดั้งเดิมตกลงไปตามเส้นทั่วไปหรือใกล้พอที่หนึ่งแล้วคอลเลกชันของเส้นโค้งที่พวกเขาสร้างขึ้นในการแปลง Hough มักจะมีจุดตัดร่วมที่สอดคล้องกับบรรทัดทั่วไปนั้น ด้วยการค้นหาจุดที่รุนแรงที่สุดเหล่านี้ในการแปลง Hough เราสามารถอ่านวิธีแก้ปัญหาที่ดีสำหรับปัญหาดั้งเดิม
ในการเริ่มต้นกับข้อมูลเหล่านี้ก่อนอื่นฉันต้องตัดสิ่งเสริม (แกน, เครื่องหมายติ๊กและป้ายกำกับ) ออกและสำหรับการวัดที่ดีให้ตัดจุดที่อยู่ภายนอกที่ด้านล่างขวาและโรยไปตามแกนด้านล่าง (เมื่อสิ่งนั้นไม่ถูกครอบตัดขั้นตอนก็ยังใช้งานได้ดี แต่มันยังตรวจจับแกน, เฟรม, ลำดับเชิงเส้นของเห็บ, ลำดับเชิงเส้นของฉลากและแม้กระทั่งจุดที่วางอยู่บนแกนด้านล่าง!)
img = Import["http://i.stack.imgur.com/SkEm3.png"]
i = ColorNegate[Binarize[img]]
crop2 = ImageCrop[ImageCrop[i, {694, 531}, {Left, Bottom}], {565, 467}, {Right, Top}]
(นี่และรหัสที่เหลืออยู่ในMathematica )
ในแต่ละจุดในภาพนี้จะมีช่วงโค้งแคบ ๆ ในการแปลง Hough ซึ่งมองเห็นได้ที่นี่ พวกเขาเป็นคลื่นไซน์:
hough2 = Radon[crop2, Method -> "Hough"] // ImageAdjust
สิ่งนี้ทำให้มองเห็นได้อย่างชัดเจนถึงความรู้สึกที่คำถามนั้นเป็นปัญหาการจัดกลุ่มบรรทัด : การแปลง Hough ช่วยลดปัญหาการจัดกลุ่มจุดซึ่งเราสามารถใช้วิธีการจัดกลุ่มใด ๆ ที่เราชอบ
ในกรณีนี้การจัดกลุ่มมีความชัดเจนว่าการทำโพสต์อย่างง่ายของ Hough transform ที่พอเพียง ในการระบุตำแหน่งที่มีความเข้มมากที่สุดในการแปลงรูปฉันได้เพิ่มความคมชัดและทำให้การแปลงเบลอบนรัศมีประมาณ 1%: นั่นเปรียบได้กับขนาดเส้นผ่าศูนย์กลางของจุดพล็อตในภาพต้นฉบับ
blur = ImageAdjust[Blur[ImageAdjust[hough2, {1, 0}], 8]]
การกำหนดผลลัพธ์ใหม่ให้แคบลงเหลือสอง blobs เล็ก ๆ ซึ่ง centroids จะระบุจุดที่มีความเข้มมากที่สุดได้อย่างสมเหตุสมผล: สิ่งเหล่านี้ประเมินเส้นที่ติดตั้งไว้
comp = MorphologicalComponents[blur, 0.777]) // Colorize
0.777
ด้านซ้ายของภาพสอดคล้องกับทิศทาง 0 องศา (แนวนอน) และเมื่อเรามองจากซ้ายไปขวามุมนั้นจะเพิ่มขึ้นเป็นเส้นตรงเป็น 180 องศา Interpolating ฉันคำนวณว่าสอง blobs อยู่กึ่งกลางที่ 19 และ 57.1 องศาตามลำดับ นอกจากนี้เรายังสามารถอ่านค่าตัดขวางจากตำแหน่งแนวตั้งของ blobs ข้อมูลนี้ให้ผลเริ่มต้นพอดี:
width = ImageDimensions[blur][[1]];
slopes = Module[{x, y, z}, ComponentMeasurements[comp, "Centroid"] /.
Rule[x_, {y_, z_}] :> Round[((y - 1/2)/(width - 1)) 180., 0.1]
]
{19. , 57.1}
ในลักษณะที่คล้ายกันเราสามารถคำนวณจุดตัดที่สอดคล้องกับความลาดชันเหล่านี้ได้
(เส้นสีแดงตรงกับจุดสีชมพูเล็ก ๆ ในภาพก่อนหน้าและเส้นสีน้ำเงินตรงกับ aqua blob ที่ใหญ่กว่า)
ในระดับที่ยอดเยี่ยมวิธีการนี้จะจัดการกับปัญหาแรกโดยอัตโนมัติ: การเบี่ยงเบนจากการเชิงเส้นทำให้คะแนนของความรุนแรงมากที่สุด แต่โดยทั่วไปแล้วจะไม่เปลี่ยนแปลงมากนัก จุดที่อยู่ไกลออกไปตรงไปตรงมาจะให้เสียงรบกวนในระดับต่ำตลอดการแปลง Hough ซึ่งจะหายไประหว่างขั้นตอนหลังการประมวลผล
ณ จุดนี้เราสามารถจัดเตรียมการประมาณการเหล่านี้เป็นค่าเริ่มต้นสำหรับอัลกอริทึม EM หรือเครื่องมือลดโอกาสที่จะเกิดขึ้น (ซึ่งหากได้รับการประมาณการที่ดี ที่ดีขึ้นแม้ว่าจะมีการใช้ประมาณการถดถอยที่แข็งแกร่งเช่นซ้ำ reweighted น้อยสแควร์ มันสามารถให้น้ำหนักการถดถอยทุกจุด ตุ้มน้ำหนักต่ำหมายถึงจุดที่ไม่ได้อยู่ในบรรทัด ใช้ประโยชน์จากน้ำหนักเหล่านี้หากต้องการเพื่อกำหนดแต่ละจุดให้เป็นแนวที่เหมาะสม จากนั้นเมื่อมีการจำแนกคะแนนคุณสามารถใช้กำลังสองน้อยที่สุดธรรมดา (หรือขั้นตอนการถดถอยอื่น ๆ ) แยกกันในจุดสองกลุ่ม