Upgrade to Pro — share decks privately, control downloads, hide ads and more …

業務改善の面白さ~毎日更新されるビジュアルコンテンツの差分を わかりやすくするためのプロトタイプを作るまで~

業務改善の面白さ~毎日更新されるビジュアルコンテンツの差分を わかりやすくするためのプロトタイプを作るまで~

PyCon JP
2022 2022/10/14

業務改善の面白さ
毎日更新されるビジュアルコンテンツの差分を
わかりやすくするためのプロトタイプを作るまで

Marina Nakagawa

October 13, 2022
Tweet

More Decks by Marina Nakagawa

Other Decks in Technology

Transcript

  1. 1
    ۀ຿վળͷ໘ന͞
    ຖ೔ߋ৽͞ΕΔϏδϡΞϧίϯςϯπͷࠩ෼Λ
    Θ͔Γ΍͘͢͢ΔͨΊͷϓϩτλΠϓΛ࡞Δ·Ͱ
    ೔ຊܦࡁ৽ฉࣾɹத઒ ສᣦಸ
    PyCon JP 2022 2022/10/14

    View Slide

  2. 2
    Marina Nakagawa
    ೔ຊܦࡁ৽ฉࣾͷΤϯδχΞ
    ೔ܦϏδϡΞϧσʔλͷίϯςϯπ੍࡞

    ΠϯϑϥपΓͷվળͳͲͳͲ
    ࣗಈԽ͕޷͖Ͱ͢ʂ

    View Slide

  3. 3
    ຊ೔࿩͢͜ͱ
    ఆظతʹߋ৽͞ΕΔίϯςϯπͷ՝୊
    ೔ܦϏδϡΞϧσʔλͱ͸
    1
    2
    3 ࠩ෼ݕ஌ͷϓϩτλΠϓΛ࡞Δ
    ݁Ռͱ·ͱΊ
    4

    View Slide

  4. 4
    ೔ܦϏδϡΞϧσʔλͱ͸
    1

    View Slide

  5. 5

    View Slide

  6. 6
    จষ ਤઆ σʔλ Πϥετ ࣸਅ
    ͋ΒΏΔදݱΛۦ࢖ͯ͠
    etc…
    χϡʔεΛΘ͔Γ΍͘͢఻͑Δ

    View Slide

  7. 7
    https://vdata.nikkei.com/newsgraphics/sanin2022-analysis/

    View Slide

  8. 8
    https://vdata.nikkei.com/newsgraphics/party-poll-votes-map/

    View Slide

  9. 9
    https://vdata.nikkei.com/newsgraphics/coronavirus-world-map/

    View Slide

  10. 10
    https://vdata.nikkei.com/newsgraphics/clear-accounting/clear-accounting/

    View Slide

  11. 11
    https://vdata.nikkei.com/

    View Slide

  12. 12
    ɾ௚ײతʹΘ͔Γ΍͘͢ɺ୹࣌ؒͰಡΊΔίϯςϯπ
    ɾैདྷͷใಓදݱΛਐԽͤ͞ΔࢼΈ
    ɾϢʔβʔʹͱͬͯ໾ཱͭίϯςϯπ
    ɾଉͷ௕͍ίϯςϯπ
    ɾطଘͷํ๏Ҏ֎ͷίϯςϯπͷྲྀ௨ํ๏ͱϊ΢ϋ΢
    ͦΕΒΛ࡞Δ৔͕
    ೔ܦϏδϡΞϧσʔλ

    View Slide

  13. 13
    هऀ

    ఻͑Δ΂͖͜ͱ
    σβΠφʔ
    ఻͑ํ
    ΤϯδχΞ 

    ఻͑ΔͨΊͷ࢓૊Έ

    View Slide

  14. 14
    هऀ

    ఻͑Δ΂͖͜ͱ
    σβΠφʔ
    ఻͑ํ
    ΤϯδχΞ 

    ఻͑ΔͨΊͷ࢓૊Έ

    View Slide

  15. 15
    هऀ

    هࣄίϯςϯπͷ಺༰ɾσʔλ
    σβΠφʔ
    ίϯςϯπͷઃܭɾσβΠϯ
    ΤϯδχΞ 

    ഑৴ͷ࢓૊Έ

    Ϣʔβʔ͔ΒͷΠϯλϥΫγϣϯΛؚΉ࡞Γ

    View Slide

  16. 16
    هऀ

    σβΠφʔ ΤϯδχΞ

    View Slide

  17. 17
    ఆظతʹߋ৽͞ΕΔίϯςϯπͷ՝୊
    2

    View Slide

  18. 18
    ఆظతʹߋ৽͞ΕΔίϯςϯπͷ
    جຊతͳ੍࡞ͷྲྀΕ

    View Slide

  19. View Slide

  20. هऀνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    هऀνʔϜͷ੹೚ऀ͕ެ։Λ൑அ
    $*Λ༻͍ͨσϓϩΠϑϩʔͱ͸
    ҟͳΔϑϩʔͰຊ൪ʹ൓ө

    View Slide

  21. هऀνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    هऀνʔϜͷ
    ੹೚ऀ͕ެ։Λ൑அ
    هऀ͕੹೚Λ࣋ͭσʔλ͸
    جຊతʹຖ೔ߋ৽͞ΕΔ

    View Slide

  22. σβΠφʔɾΤϯδχΞνʔϜ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $*ͰϦϦʔε

    View Slide

  23. σβΠφʔɾΤϯδχΞνʔϜ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $*ͰϦϦʔε
    ࣌ظʹΑͬͯݟͤΔσʔλ΍
    ݟͤํΛมߋ͢Δͱ͖ʹߋ৽

    View Slide

  24. هऀνʔϜ
    σβΠφʔɾΤϯδχΞνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $*ͰϦϦʔε
    هऀνʔϜͷσʔλͱ
    σβΠφʔɾΤϯδχΞνʔϜͷ੒Ռ෺͕
    ߹Θ͞Δͷ͸ຊ൪؀ڥ
    ˞΋ͪΖΜ։ൃ؀ڥ΋ଘࡏ͢Δ

    View Slide

  25. View Slide

  26. 26

    View Slide

  27. ࠓ೔ͷάϥϑ͸
    ߋ৽͞Ε͍ͯΔʁ
    هࣄίϯςϯπͷ
    ਺ࣈ͸ਖ਼͘͠
    දࣔ͞Ε͍ͯΔʁ
    άϧʔϓԽ͞Εͨ
    ԣάϥϑ͸େৎ෉ʁ
    େ෯վमͨ͠ͱ͜Ζ͸
    ͖ͪΜͱදࣔ͞Ε͍ͯΔʁ
    ೔෇͸
    ߋ৽͞Ε͍ͯΔʁ

    View Slide

  28. ࠓ೔ͷάϥϑ͸
    ߋ৽͞Ε͍ͯΔʁ
    هࣄίϯςϯπͷ
    ਺ࣈ͸ਖ਼͘͠
    දࣔ͞Ε͍ͯΔʁ
    άϧʔϓԽ͞Εͨ
    ԣάϥϑ͸େৎ෉ʁ
    େ෯վमͨ͠ͱ͜Ζ͸
    ͖ͪΜͱදࣔ͞Ε͍ͯΔʁ
    ຖ೔ߋ৽͞ΕΔ
    σʔλܥ
    ೔෇͸
    ߋ৽͞Ε͍ͯΔʁ

    View Slide

  29. ࠓ೔ͷάϥϑ͸
    ߋ৽͞Ε͍ͯΔʁ
    هࣄίϯςϯπͷ
    ਺ࣈ͸ਖ਼͘͠
    දࣔ͞Ε͍ͯΔʁ
    άϧʔϓԽ͞Εͨ
    ԣάϥϑ͸େৎ෉ʁ
    େ෯վमͨ͠ͱ͜Ζ͸
    ͖ͪΜͱදࣔ͞Ε͍ͯΔʁ
    վम࣌ʹ
    ߋ৽͞ΕΔܥ

    View Slide

  30. ࠓ೔ͷάϥϑ͸
    ߋ৽͞Ε͍ͯΔʁ
    هࣄίϯςϯπͷ
    ਺ࣈ͸ਖ਼͘͠
    දࣔ͞Ε͍ͯΔʁ
    άϧʔϓԽ͞Εͨ
    ԣάϥϑ͸େৎ෉ʁ
    େ෯վमͨ͠ͱ͜Ζ͸
    ͖ͪΜͱදࣔ͞Ε͍ͯΔʁ
    ֬ೝ͢ΔϙΠϯτ͕ଟ͍
    &
    ݟΔϙΠϯτ͕ҟͳΔ
    ใಓػؔͱͯ͠͸σʔλͷνΣοΫ͸ݫ͘͢͠Δඞཁ͕͋Δ͕ɾɾɾ

    View Slide

  31. 31

    View Slide

  32. 32

    View Slide

  33. 33
    ໨diff!!!!
    (͜Ε͸σΟϨΫλʔ͕ਏ͍)

    View Slide

  34. 34
    ໨diffؒҧ͍୳͠

    View Slide

  35. 35
    ໨diffؒҧ͍୳͠

    View Slide

  36. 36
    ࠷ऴతͳ൑அ͸ίϯϐϡʔλͰ͸ͳ͘ਓ͕ؒߦ͏͕
    ͤΊͯ
    ֬ೝ͢ΔՕॴ͕໌֬ʹͳΕ͹͍͍ͷʹɾɾɾɾ

    View Slide

  37. 37
    ͦ͏ͩʂ
    ϏδϡΞϧϦάϨογϣϯςετΛԠ༻ͯ͠
    ͏·͍͜ͱ࢓૊ΈԽͰ͖ͳ͍ͩΖ͏͔ʁʁʁ

    View Slide

  38. 38
    ࠩ෼ݕ஌ͷϓϩτλΠϓΛ࡞Δ
    3

    View Slide

  39. 39
    Try1
    ϏδϡΞϧϦάϨογϣϯςετπʔϧreg-suit
    Ͱ΍ͬͯΈΑ͏

    View Slide

  40. 40
    https://github.com/reg-viz/reg-suitΑΓҾ༻

    View Slide

  41. NBTUFSϒϥϯν
    NBTUFS͔Β
    ੾ͬͨ࣌఺ͷϖʔδ
    QVTIͯ͠
    ߋ৽͞Εͨϖʔδ
    ൺֱͯࠩ͠෼Λग़͢

    View Slide

  42. (JU)VCʹQVTI͢Δ
    $*্Ͱ
    ϖʔδͷεΫϦʔϯγϣοτΛ࡞੒
    SFHTVJUͰ
    εΫϦʔϯγϣοτೖͬͨσΟϨΫτϦΛࢦఆ
    4ʹੜ੒ͨ͠ϖʔδΛ্͛Δ
    (JU)VCͷίϝϯτʹ
    ௨஌͕ඈͿ

    View Slide

  43. (JU)VCʹQVTI͢Δ
    $*্Ͱ
    ϖʔδͷεΫϦʔϯγϣοτΛ࡞੒
    SFHTVJUͰ
    εΫϦʔϯγϣοτೖͬͨσΟϨΫτϦΛࢦఆ
    4ʹੜ੒ͨ͠ϖʔδΛ্͛Δ
    (JU)VCͷίϝϯτʹ
    ௨஌͕ඈͿ
    ؤுͬͯίʔυΛॻ͘ͷ͸
    ͚ͩ͜͜ʂ

    View Slide

  44. (JU)VCʹQVTI͢Δ
    $*্Ͱ
    ϖʔδͷεΫϦʔϯγϣοτΛ࡞੒
    SFHTVJUͰ
    εΫϦʔϯγϣοτೖͬͨσΟϨΫτϦΛࢦఆ
    4ʹੜ੒ͨ͠ϖʔδΛ্͛Δ
    (JU)VCͷίϝϯτʹ
    ௨஌͕ඈͿ
    ͜ΕҎ߱͸
    SFHTVJU͕ࣗಈͰ΍ͬͯ͘Ε·͢

    View Slide

  45. 13্ʹϦάϨογϣϯςετͷ
    ݁ՌΛදࣔ͢Δػೳ
    EJ
    ff
    ͷϨϙʔτ΋
    ࣗಈੜ੒Ͱ͖Δ

    View Slide

  46. ઃఆͨ͠4ʹ
    Ϩϙʔτ͕ੜ੒͞ΕΔ
    ҰཡͱͳͬͯΘ͔Γ΍͍͢

    View Slide

  47. ࠩ෼ͷݟͤํ΋
    ύλʔϯ༻ҙ͞Ε͍ͯΔ

    View Slide

  48. 48
    ͏·͍͔͘ͳ͔ͬͨϙΠϯτ1
    ͜ͷίϯςϯπͰreg-suitΛ࢖͑ͳ͍ࣄ৘͕͋ͬͨ

    View Slide

  49. (JU)VCͰ؅ཧ͍ͯ͠ͳ͍΋ͷ
    දࣔ͢Δσʔλࣗମ͸

    εϓϨουγʔτͰ؅ཧ
    (JU)VCͰ؅ཧ͍ͯ͠Δ΋ͷ
    )5.-΍$44΍ը૾ͳͲͷϦιʔε

    View Slide

  50. هऀνʔϜ
    σβΠφʔɾΤϯδχΞνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $JSDMF$*ͰϦϦʔε
    هऀνʔϜͷσʔλͱ
    σβΠφʔɾΤϯδχΞνʔϜͷ੒Ռ෺͕
    ߹Θ͞Δͷ͸ຊ൪؀ڥ
    ˞΋ͪΖΜ։ൃ؀ڥ΋ଘࡏ͢Δ
    هऀνʔϜͷ
    ੹೚ऀ͕ެ։Λ൑அ

    View Slide

  51. هऀνʔϜ
    σβΠφʔɾΤϯδχΞνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $JSDMF$*ͰϦϦʔε
    ຖ೔ͷσʔλूܭͨ݁͠Ռ͕
    (JU)VCͰ؅ཧ͞Ε͍ͯͳ͍

    View Slide

  52. هऀνʔϜ
    σβΠφʔɾΤϯδχΞνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $JSDMF$*ͰϦϦʔε
    ຊ൪؀ڥͷϖʔδͰ
    ࠓݱࡏදࣔ͞Ε͍ͯΔ΋ͷͱ
    աڈදࣔ͞Ε͍ͯͨ΋ͷΛൺֱ͍ͨ͠

    View Slide

  53. 53
    ͏·͍͔͘ͳ͔ͬͨϙΠϯτ2
    ຊ౰ʹ࢖ͬͯ΋Β͑Δ͔࣮༻ੑͷݒ೦
    - GitHubʹ͔͠௨஌͕͜ͳ͍ɻ

    - هऀʹ΋GitHubΞΧ΢ϯτ͕ඞཁ

    - ࠩ෼ΛݟΔ·Ͱͷ໿4ΫϦοΫͷนΛӽ͑Δ

    - Slack νϟϯωϧ,GitHubͷPR,reg-suit,reg-suitͷத

    View Slide

  54. 54
    ͏·͍͔͘ͳ͔ͬͨϙΠϯτ2
    ຊ౰ʹ࢖ͬͯ΋Β͑Δ͔࣮༻ੑͷݒ೦
    - GitHubʹ͔͠௨஌͕͜ͳ͍ɻ

    - هऀʹ΋GitHubΞΧ΢ϯτ͕ඞཁ

    - ࠩ෼ΛݟΔ·Ͱͷ໿4ΫϦοΫͷนΛӽ͑Δ

    - Slack νϟϯωϧ,GitHubͷPR,reg-suit,reg-suitͷத
    ຊ౰ʹ਺ճΫϦοΫͯ͘͠ΕΔʁʁʁ
    Θ͟Θ͟ݟΔͷΊΜͲ͘͘͞ͳ͍ʁʁʁ

    View Slide

  55. 55
    ͜͏ͳͬͨΒ͍͍ͳͱໝ૝ͯͨ͜͠ͱ
    Nikkei
    ————
    ————
    ————
    ————
    ௨஌νϟϯωϧ
    ௨஌bot
    1Click
    ͲΜͳ৬छͰ΋
    ͚ͩ͜͜ݟ͓͚ͯ͹͍͍ʂ
    ͱ͍͏ঢ়ଶΛ࡞Γ͍ͨ
    ————
    ————
    ————

    View Slide

  56. 56
    ͜͏ͳͬͨΒ͍͍ͳͱໝ૝ͯͨ͜͠ͱ
    Nikkei
    ————
    ————
    ————
    ————
    ௨஌νϟϯωϧ
    ௨஌bot
    1Click
    ͲΜͳ৬छͰ΋
    ͚ͩ͜͜ݟ͓͚ͯ͹͍͍ʂ
    ঢ়ଶΛ࡞Γ͍ͨ
    ֬ೝ͢Δ΂͖Օॴ͕໌֬ʹʂ
    ࠷ऴతͳਓؒͷ൑அͷิॿʹͳΔʂ(͸ͣ)

    View Slide

  57. 57
    ཁ݅Λߟ͑Δ
    ɾهऀνʔϜଆ͕σʔλΛߋ৽͢Δͱ͖ʹɺࣗಈͰલͷঢ়ଶͱࠓͷঢ়ଶͱͦͷࠩ෼͕දࣔ͢Δ


    ɾ৬छ໰Θͣɺ୭΋͕ͦͷࠩ෼Λ֬ೝ͢Δ͜ͱ͕Ͱ͖Δঢ়ଶʹ͢Δ


    ɾ࿈བྷखஈʹSlackΛར༻͍ͯ͠ΔͷͰɺͦͷ݁Ռ͕Slackʹ·ͱΊΒΕΔͱΑ͍

    View Slide

  58. 58
    αΫοͱϓϩτλΠϓΛ
    ࡞ͬͯΈΔ
    SFHTVJUͰֶΜͩ͜ͱΛ׆͔ͯ͠

    View Slide

  59. 59
    ࠩ෼Λݕग़ͯ͠ɺSlackʹ౤Լ͢Δ͘͠ΈΛߟ͑ͨ
    1.ར༻͢Δπʔϧ΍ϥΠϒϥϦྨΛબఆ͢Δ
    2.࣮ߦํ๏ΛܾΊΔ
    3.ൺֱը૾Λ༻ҙ͢Δ
    4.ը૾ͷߴ͞Λἧ͑ͯɺൺֱ΍Ճ޻͠΍͘͢͢Δ
    5.ը૾ͷࠩ෼Λݕग़͢ΔͨΊͷ४උΛ͢Δ
    6.ը૾ͷࠩ෼Λݕग़͢Δ
    7.ࠩ෼͕͋Ε͹࡞੒ͨ͠εΫϦʔϯγϣοτΛS3ʹΞοϓϩʔυ͢Δ
    8.Slack౤ߘ༻ʹը૾Λ߹੒͢Δ
    9.Slackʹ౤ߘ͢Δ

    View Slide

  60. 60
    1.ར༻͢Δπʔϧ΍ϥΠϒϥϦྨΛબఆ͢Δ
    ը૾Ͱࠩ෼Λݕग़͢ΔͳΒ →OpenCV͕࢖͑ͯ
    Webը૾ΛεΫγϣ͢ΔͳΒˠWebࣗಈԽπʔϧͰεΫγϣΛͱΖ͏
    աڈը૾Λอଘ͢ΔͳΒˠS3͕ྑͦ͞͏
    ·͋ɺϓϩτλΠϓͩͬ͠͞ͱPythonͰࢼͦ͏ʂ
    Ұ୴Google ColaboratoryͰϛχϛχϓϩτλΠϓΛ࡞ͬͯΈΔ
    →ΠέΔʂΛ֬৴

    View Slide

  61. 61
    2.࣮ߦํ๏ΛܾΊΔ
    Google Colaboratory Ͱܾ·ͬͨ࣌ؒʹىಈͰ͖ͨΒ͍͍ͷʹ
    ࠓͷܖ໿ͩͱͰ͖ͳ͔ͬͨͷͰ
    GitHubͱ࿈ܞ͍ͯ͠ΔCircleCIͰɺ
    σʔλ੔ܗͱ൓ө͕ऴΘΔޕޙ̑࣌ʹ࣮ߦ͢Δ͜ͱʹ
    ※Pro+ͩͱεέδϡʔϧػೳ͕͋Γ·͢

    (https://github.com/googlecolab/colabtools/wiki/Scheduled-notebooks)

    View Slide

  62. $JSDMF$*Ͱ
    ϖʔδͷεΫγϣΛੜ੒
    4͔Βલճߋ৽࣌ʹࡱӨͨ͠
    εΫγϣΛμ΢ϯϩʔυ
    62
    3.ൺֱը૾Λ༻ҙ͢Δ

    View Slide

  63. $JSDMF$*Ͱ
    ϖʔδͷεΫγϣΛੜ੒
    4͔Βલճߋ৽࣌ʹࡱӨͨ͠
    εΫγϣΛμ΢ϯϩʔυ
    63
    3.ൺֱը૾Λ༻ҙ͢Δ

    View Slide

  64. 64
    SCREENSHOT_WIDTH_SIZE = 800


    SCREENSHOT_HIGHT_SIZE = 12000


    TARGET_URL = "https://vdata.nikkei.com/newsgraphics/coronavirus-japan-vaccine-
    status/"


    WAIT_TIME = 10


    # ΢ΣϒυϥΠόʔͱΦϓγϣϯͷઃఆ


    options = webdriver.ChromeOptions()


    options.add_argument('--headless')


    options.add_argument('--incognito')


    options.add_argument('--no-sandbox')


    options.add_argument('--disable-dev-shm-usage')


    driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)


    driver.get(TARGET_URL)


    driver.set_window_size(SCREENSHOT_WIDTH_SIZE, SCREENSHOT_HIGHT_SIZE)


    time.sleep(WAIT_TIME)


    driver.save_screenshot("test-reports/current_page_screenshot.png")


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  65. $JSDMF$*Ͱ
    ϖʔδͷεΫγϣΛੜ੒
    4͔Βલճߋ৽࣌ʹࡱӨͨ͠
    εΫγϣΛμ΢ϯϩʔυ
    65
    3.ൺֱը૾Λ༻ҙ͢Δ

    View Slide

  66. 66
    # S3ʹΞοϓϩʔυ


    import boto3


    # S3ͷϑΝΠϧμ΢ϯϩʔυɺΞοϓϩʔυͷઃఆ


    client = boto3.client(


    's3',


    aws_access_key_id= {AWS ΞΫηεΩʔID},


    aws_secret_access_key= {AWS γʔΫϨοτΩʔ},


    )


    client.download_file(


    '{S3໊}',


    '{S3ͷύε໊}/screenshot.png',


    'test-reports/past_page_screenshot.png'


    )


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  67. ଍Γͳ͍௕͞͸0QFO$7Ͱ
    ന৭෦෼Λ௥Ճͯ͠ௐ੔
    4.ը૾ͷߴ͞Λἧ͑ͯɺൺֱ΍Ճ޻͠΍͘͢͢Δ

    View Slide

  68. 68
    #===============================================


    #ɹಉ͡αΠζʹͳΔΑ͏ʹԼʹۭനΛೖΕͯϦαΠζ


    #===============================================


    color = (255, 255, 255)


    if img_current.shape[0] <= img_past.shape[0]:


    bottom = img_past.shape[0] - img_current.shape[0]


    img_current = cv2.copyMakeBorder(img_current, 0,bottom, 0, 0,


    cv2.BORDER_CONSTANT,


    value=color,


    )


    else:


    bottom = img_current.shape[0] - img_past.shape[0]


    img_past = cv2.copyMakeBorder(img_past, 0, bottom, 0, 0,


    cv2.BORDER_CONSTANT,


    value=color,


    )


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  69. มߋલͱมߋޙΛൺֱͯ͠
    ࠩ෼ϚεΫΛ࡞੒͢Δ
    5.ը૾ͷࠩ෼Λݕग़͢ΔͨΊͷ४උΛ͢Δ

    View Slide

  70. 70
    #===============================================


    # ը૾ͷࠩ෼Λ࡞Δ


    #===============================================


    fgbg = cv2.bgsegm.createBackgroundSubtractorMOG(history=2)


    #ϚεΫͷܭࢉ


    fgmask = fgbg.apply(img_current)


    fgmask = fgbg.apply(img_past)


    cv2.imwrite('test-reports/mask.png', fgmask)


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  71. 6.ը૾ͷࠩ෼ΛΘ͔Γ΍͘͢͢Δ
    ϚεΫ͚ͩͩͱࠩ෼͕Θ͔Βͳ͍ͷͰ
    ը૾Λ҉ͯ͘͠ॏͶΔ

    View Slide

  72. 72
    #===============================================


    # ը૾Λ҉ͯࠩ͘͠෼ϚεΫΛॏͶɺ


    # ࠩ෼ͷݕग़ͷ݁Ռ͕෼͔ΔΑ͏ʹग़ྗ͢Δ


    #===============================================


    # ݱࡏͷεΫγϣΛগ͠҉͘͢Δ


    img_result = img_current // 4


    # ϚεΫͰࠩ෼ͷ͋Δͱ͜Ζ͚ͩ྘ΛࡌͤΔ


    img_result[fgmask==255] = (0, 255, 0)


    cv2.imwrite('test-reports/result.png', img_result)
    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  73. 8.Slack౤ߘ༻ʹը૾Λ߹੒͢Δ
    4MBDLͰ௨஌ͨ͠ͱ͖ʹΘ͔Γ΍͍͢Α͏ʹ
    มߋલɺมߋޙɺࠩ෼ͷ̏ͭΛ଍͠߹Θͤ
    Ұͭͷը૾ʹ͢Δ

    View Slide

  74. 8.Slack౤ߘ༻ʹը૾Λ߹੒͢Δ
    ͜͏ͳΔͱɺ
    Կ͕Ͳ͏มΘ͍ͬͯΔͷ͔Θ͔Βͳ͍

    View Slide

  75. 75
    #=============================


    # ը૾ͷ߹੒(Slack౤ߘ༻)


    #=============================


    percentage_to_resize = 0.5


    img_summary = cv2.hconcat([img_current, img_past, img_result])


    img_summary = cv2.resize(


    img_summary ,


    (int(img_summary.shape[1] * percentage_to_resize),


    int(img_summary.shape[0] * percentage_to_resize))


    )


    cv2.imwrite('test-reports/summary.png', img_summary)


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  76. 7.ࠩ෼͕͋Ε͹࣍ճͷൺֱ༻ʹ࡞੒ͨ͠εΫϦʔϯ
    γϣοτΛS3ʹΞοϓϩʔυ͢Δ
    Կ΋͠ͳ͍
    ࠩ෼͋Γʂ

    ࠩ෼ͳ͠ʂ

    View Slide

  77. 77
    #=======================================================


    # S3ʹը૾ΛΞοϓϩʔυ͢Δ


    #=======================================================


    client.upload_file(


    'test-reports/current_page_screenshot.png',


    '{S3໊}',


    ‘{S3ͷύε໊}/screenshot.png'


    )


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  78. 9.Slackʹ౤ߘ͢Δ
    Ұຕʹ·ͱΊͨํ͕ݟ΍͍͢ʂ

    View Slide

  79. มߋޙ มߋલ ࠩ෼

    View Slide

  80. 80
    ໨diffؒҧ͍୳͠(αϙʔτ෇͖)

    View Slide

  81. 81
    #======================================================


    # ࠩ෼͕͋Ε͹files uploadAPIͰSlackʹ௨஌


    #======================================================


    def postMessageWithFiles(message, fileList, channel):


    slack_client = slack_sdk.WebClient(token=SLACK_TOKEN)


    for file in fileList:


    upload = slack_client.files_upload(file=file, filename=file)


    message = message + ”<“ + upload['file']['permalink'] + "| >"


    outPut = slack_client.chat_postMessage(


    channel = channel,


    text = message


    )


    #=======================================================


    # มߋΛݕ஌ͨ࣌͠


    #=======================================================


    if np.array_equal(img_current, img_past):


    postMessageWithFiles(


    message = " `ίϩφ೔ຊϫΫνϯίϯςϯπͷࠩ෼Λݕ஌͠·ͨ͠ʂ”,


    fileList = ['test-reports/summary.png'],


    channel = "{௨஌͍ͨ͠νϟϯωϧ໊}",


    )


    ※ίʔυ͸Ұ෦ൈਮ

    View Slide

  82. 82
    ※ίʔυ͸Ұ෦ൈਮ
    ΋͠΋ະདྷͰɺ
    ࠩ෼Λݟ͍ͨϖʔδ͕ෳ਺ʹ૿͑ͨ࣌

    View Slide

  83. 83
    ݁Ռͱ·ͱΊ
    3

    View Slide

  84. 84
    هऀ

    σβΠφʔ ΤϯδχΞ
    ศརͳ࢓૊ΈΛ
    ͋Γ͕ͱ͏͍͟͝·͢
    ໌Β͔ʹ͓͔͍͠Օॴ͕ͳ͍͔
    ؆୯ʹ൑ผͰ͖Δͷ͸͋Γ͕͍ͨ
    σʔλͷܻ਺ʹΑͬͯϨΠΞ΢τ͕
    มΘΔཁૉ͕͋Δɻ
    ҙਤ͍ͯ͠ͳ͍ϨΠΞ΢τʹ
    ͳ͍ͬͯͳ͍͔͕Ұ໨Ͱ෼͔Δͷ͕
    ྑ͍
    ಋೖޙͷ੠

    View Slide

  85. 85
    هऀ

    σβΠφʔ ΤϯδχΞ
    ศརͳ࢓૊ΈΛ
    ͋Γ͕ͱ͏͍͟͝·͢
    ໌Β͔ʹ͓͔͍͠Օॴ͕ͳ͍͔
    ؆୯ʹ൑ผͰ͖Δͷ͸͋Γ͕͍ͨ
    σʔλͷܻ਺ʹΑͬͯϨΠΞ΢τ͕
    มΘΔཁૉ͕͋Δɻ
    ҙਤ͍ͯ͠ͳ͍ϨΠΞ΢τʹ
    ͳ͍ͬͯͳ͍͔͕Ұ໨Ͱ෼͔Δͷ͕ྑ͍
    ಋೖޙͷ੠
    Ͱ΋ɾɾɾɾ
    ͩΜͩΜݟΒΕͳ͘ͳͬͯ͠·͏

    View Slide

  86. 86
    هऀ

    σβΠφʔ ΤϯδχΞ
    ޕޙ̑࣌ఆظ࣮ߦ͡Όͳͯ͘
    ग़͢௚લʹνΣοΫͰ͖ΔΑ͏ͳػߏ
    ͕Α͔ͬͨ
    վળϙΠϯτ

    View Slide

  87. هऀνʔϜ
    σβΠφʔɾΤϯδχΞνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $*ͰϦϦʔε
    ͜ͷ࣌఺Ͱެ։ͱಉ࣌ʹ
    -BNCEBΛىಈ
    ͞Βʹվળ͢ΔͳΒ

    View Slide

  88. 88
    هऀ

    σβΠφʔ ΤϯδχΞ
    ผͷϒϥ΢β΍ϞόΠϧαΠζͳͲ
    ͍Ζ͍Ζͳը໘ύλʔϯͰ
    ݕূͰ͖ͨ΄͏͕҆৺ײ͕ߴ·Δɻ
    վળϙΠϯτ
    ίϯςϯπ಺ͷ্෦ͷจষ͕
    มߋ͞Εͯɺߦ਺͕มΘͬͯ͠
    ·͏ͱϨΠΞ΢τ͕͢΂ͯԼʹ
    ͣΕͨͱݕग़͞ΕΔͱ͍͏৔߹
    ͕͋Δɻ

    View Slide

  89. هऀνʔϜ
    σβΠφʔɾΤϯδχΞνʔϜ
    εϓϨουγʔτͰ
    ຖ೔σʔλूܭˍνΣοΫ
    վम͕͋Δ৔߹
    (JU)VCͰϦιʔε؅ཧ
    $*ͰϦϦʔε
    άϥϑͷը૾ͷݕग़͚ͩʹಛԽ
    ͞Βʹվળ͢ΔͳΒ

    View Slide

  90. 90
    Pythonͷศར͞
    ΍Γ͍ͨ͜ͱʹରͯ͠ɺπʔϧ͕ἧ͍ͬͯͯ
    ਺ेߦͰ͙͢ʹࢼ͢͜ͱ͕Ͱ͖Δշద͕͞࠷ߴ

    View Slide

  91. 91
    هऀ

    σβΠφʔ ΤϯδχΞ
    ۀ຿վળͷ໘ന͍ϙΠϯτ
    ͍ͭ΋΍͍ͬͯΔ
    ಉ͡ܗࣜ֬ೝ࡞ۀ
    ͍ͭ΋΍ͬͯΔ͚Ͳ
    ຊ൪Ͱຖ೔
    ֬ೝ͢Δ͔͠ͳ͍ͷ͔ͳʙ

    View Slide

  92. 92
    هऀ

    σβΠφʔ ΤϯδχΞ
    ۀ຿վળͷ໘ന͍ϙΠϯτ
    ͍ͭ΋΍͍ͬͯΔ
    ಉ͡ܗࣜ֬ೝ࡞ۀ
    ͍ͭ΋΍ͬͯΔ͚Ͳ
    ຊ൪Ͱຖ೔
    ֬ೝ͢Δ͔͠ͳ͍ͷ͔ͳʙ
    ʮ͜͏ͳͬͨΒ͍͍ͷʹͳʙʯ͸ɺࠔ͍ͬͯΔຊਓ͔Β
    ϐϯϙΠϯτͰ͸དྷͳ͍

    View Slide

  93. 93
    هऀ

    σβΠφʔ ΤϯδχΞ
    ۀ຿վળͷ໘ന͍ϙΠϯτ
    ͲΜͳײ͡Ͱ
    ࡞ۀ͍ͯ͠ΔΜͰ͔͢ʁʁ

    View Slide

  94. 94
    هऀ

    σβΠφʔ ΤϯδχΞ
    ۀ຿վળͷ໘ന͍ϙΠϯτ
    ͜Μͳखஈ͋Γ·͢Αʁ
    ͜͏ͨ͠Β͍͍͔΋ʁ
    ͦΜͳ͜ͱͰ͖Δͷʁʁʂʂ
    ศརʂͦΕ΄͍͠ʂ

    View Slide

  95. 95
    ·ͱΊ
    νʔϜͷಇ͖ํΛ͞Βʹշదʹ͢ΔͨΊͷछ͕

    ೔ʑͷίϛϡχέʔγϣϯͷதʹ͋Δ͔΋ʁʂ

    View Slide

  96. 96
    https://hack.nikkei.com/

    View Slide

  97. 97
    ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide