Kanazawanaoaki / cook_eyes

Implement the eyes of the cook
1 stars 2 forks source link

縦長の画像のアノテーションが上手くできていない #4

Closed Kanazawanaoaki closed 4 years ago

Kanazawanaoaki commented 4 years ago

labelmeによってアノテーションを行っているが、縦長の画像に対してのアノテーションが上手く言っていない可能性がある。 very_easy_data/train/382076.jpg

labelme --labels labels.txt very_easy_data/train/382076.jpg

Screenshot from 2020-05-17 20-56-00

labelme_draw_label_png very_easy_datasets/train/SegmentationClassPNG/382076.png 

Screenshot from 2020-05-17 20-58-40 画像が途中で切れてしまって上手くアノテーションが出来ていない気がする。

Kanazawanaoaki commented 4 years ago

そもそもの画像を反転させて、新しくアノテーションをすると上手くアノテーション出来ているように思える。 very_easy_data_kai/train/382076.jpg

labelme --labels labels.txt very_easy_data_kai/train/382076.jpg

Screenshot from 2020-05-17 20-59-24

labelme_draw_label_png very_easy_data_kai_datasets/train/SegmentationClassPNG/382076.png

Screenshot from 2020-05-17 20-59-04

Kanazawanaoaki commented 4 years ago

以前学習させたネットワークをtrainの予測を見て確認した時にも、横長の画像はそれなりに学習できていそうなのに、縦長の画像は上手く言っていないという事があった。それもこれが原因だったのかも。これからは横長の写真を使うか縦長の場合は回転させて使うのが良さそう。 Screenshot from 2020-05-16 13-10-14 Screenshot from 2020-05-16 13-10-54

knorth55 commented 4 years ago

画像をiphoneとかでとっていますか? iphoneで縦長の画像をとっている場合には、たまに画像の表示は縦長なのに画像のデータとしては横長になっていることがあります。 そうなるとlabelme_draw_みたいなプログラムで、横長と認識して可視化している可能性があります。 cv2などで画像をreadしてshapeなどをみてみると良いかと思います。

img = cv2.imread(path)
# shape = (Height, Width, Channel)
print(img.shape)

そうなっているとアノテーションもかなりおかしなことになりますね。 アノテーションが縦長画像に対して行われているのに、画像が横長としてロードされていると意味がないので そうなると学習も上手くいかないでしょう。 データセットの画像について詳しく見る必要がありそうですね

Kanazawanaoaki commented 4 years ago

ありがとうございます。
画像はiphoneでとっています。 なるほどそういうことだったんですね。
データセットの画像について確認してみようと思います。

MiyabiTane commented 4 years ago

この問題に関連して、画像が逆さまになってしまうという問題を発見しました。 iphoneで写真を撮る時はホームボタンが右側にくるようにし、外カメラで撮影するとこの問題が回避できる気がします。 iphoneで写真を撮った後に回転させてからPCに送ってもdlboxでは最初に撮ったときの情報で処理されるというのと、内カメラで撮った写真は逆さまになるのではないかというのが私の考えです。(確信はないです。)

下の図では上の画像がアノテーションしたもの、下の画像がtensorboardで見たものです。 ground-truth(下の画像の右側)の画像からアノテーションの情報と画像がずれていることがわかります。

Screenshot from 2020-05-25 15-26-00

knorth55 commented 4 years ago

@MiyabiTane ちなみに、iPhoneでみたときはtensorboardのほうが正しいですか?(つまり上下逆さまにはiPhoneではなってないんですよね) labelmeでこの画像表示した時の画面キャプチャもみてみたいです。

MiyabiTane commented 4 years ago

iPhoneで送った後、PC上で向きの操作などは一切していないです。

そして、すみません。画像(上のコメントの、上の画像がアノテーションしたもの、の方)を見て向き的に自分でiphone上で回転させたものだろうと思っていたのですが、今iphoneで編集ボタンを押すとオリジナルに戻す、という表示が出ないのでiphoneで撮ったままの画像のようです。

説明がわかりにくくて申し訳ないのですが、つまり言うと、iphoneで撮影した後、iphone上でもPC上でも、何の回転も加えていないはずだと言うことです。

ただ、普通写真をとると下の画像のような向きになるはずで、なぜ逆さまになっているのかは撮った本人もわかっていないです。。。

スクリーンショット 2020-05-25 17 05 20

MiyabiTane commented 4 years ago

labelme上の向きもiphoneと同じなので、違っているのはtensorboardだけだと思います。

Screenshot from 2020-05-25 17-02-10

Kanazawanaoaki commented 4 years ago

アノテーションをしたフォルダの画像を見ると正しい向き(?)になっていそうですが、 image_test2 (https://github.com/MiyabiTane/HIRO_LunchBox/blob/master/labelme/okazu_50/train/IMG_5765.JPG )

VOC形式にした後のJPEGImages内の画像を見ると反転されてしまっているみたいですかね? image_test (https://github.com/MiyabiTane/HIRO_LunchBox/blob/master/lunch_box_50_dataset/train/JPEGImages/IMG_5765.jpg )
VOC形式に変換する時に画像が反転されてしまうことがあるのでしょうか。

labelme_draw_label_png lunch_box_50_dataset/train/SegmentationClassPNG/IMG_5765.pngを見るとセグメンテーションは反転される前の画像の向きになっているのでそこでラベル付けのズレが生じているのが問題なのでしょうか。 image_test3

knorth55 commented 4 years ago

金沢くんの最初の人参もデータセットでは正しく縦になってたんだっけ?

knorth55 commented 4 years ago

となるとlabelmeのバグっぽいですね cc. @wkentaro

Kanazawanaoaki commented 4 years ago

僕の最初の人参の画像(iPhoneで縦長で撮影して回転など編集は一切行っていない)場合はアノテーションした時の画像が縦長、 Screenshot 2020-05-25 20:54:45 (https://github.com/Kanazawanaoaki/cook_eyes/blob/master/food_detector/food_only_data/very_easy_data/train/382076.jpg )

VOC形式に変換した時のJPEGImages内の画像が横長、
Screenshot 2020-05-25 20:55:28 (https://github.com/Kanazawanaoaki/cook_eyes/blob/master/food_detector/food_only_data/very_easy_datasets/train/JPEGImages/382076.jpg )

labelme_draw_label_png very_easy_datasets/train/SegmentationClassPNG/382076.pngで確認したときは縦長画像に対してのアノテーションが横長に無理やり変換されているようになっています。
Screenshot 2020-05-25 20:53:05

>>> import cv2
>>> img = cv2.imread("382076.jpg")
>>> print(img.shape)
(4032, 3024, 3)

なのでOpenCVで読んでも縦長に認識されているようですが、iPhoneで撮影した画像の場合labelmeのVOC変換を行う際にJPEGImagesが回転や反転して、セグメンテーションとずれてしまう事があるみたいですね。

knorth55 commented 4 years ago

なるほど、おもしろいですね つまりlabelmeの読み込みと保存で形が変わってしまっているのですね PRチャンスですね。

MiyabiTane commented 4 years ago

あ、ほんとだ、気づかなかった...。金沢くん指摘ありがとう! これが直ればiphoneの写真の撮り方や回転編集の有無を考慮しなくてよくなりそうですね。

直せたらPRですね、時間つくって頑張ってみます。

knorth55 commented 4 years ago

ちなみにlabelmeはどのコマンドをつかって、どうやってannotationしてるの? https://github.com/wkentaro/labelme/tree/master/examples/bbox_detection ここをさんこうにしてるのかな?

-- Shingo Kitagawa the University of Tokyo, JSK Lab s-kitagawa@jsk.imi.i.u-tokyo.ac.jp

2020年5月25日(月) 21:24 MiyabiTane notifications@github.com:

あ、ほんとだ、気づかなかった...。金沢くん指摘ありがとう! これが直ればiphoneの写真の撮り方や回転編集の有無を考慮しなくてよくなりそうですね。

直せたらPRですね、時間つくって頑張ってみます。

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Kanazawanaoaki/cook_eyes/issues/4#issuecomment-633546538, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACG6QX3HM23QL6YVZKGNHT3RTJPOTANCNFSM4NDLINKA .

MiyabiTane commented 4 years ago

labelme input --labels labels.txt として開いてアノテーションした後

https://github.com/MiyabiTane/HIRO_LunchBox/tree/master/labelme のようにしてvoc変換しています。

今ふと思ったのですが画像の形が変わってしまうことにpython3で実行していることが関係しているでしょうか? 金沢くんはpythonで実行していますか?

今コードを見ていたのですが99行目のnp.asarrayが悪さをしているようです。 https://github.com/MiyabiTane/HIRO_LunchBox/blob/master/labelme/labelme2voc.py

私の環境ではpythonで実行すると以下のようなエラーになります。 Traceback (most recent call last): File "./labelme2voc.py", line 143, in main() File "./labelme2voc.py", line 122, in main loc='rb', File "/home/tork/.local/lib/python2.7/site-packages/imgviz/label.py", line 169, in label2rgb legend, aabb1, aabb2, fill=(255, 255, 255) File "/home/tork/.local/lib/python2.7/site-packages/imgviz/draw.py", line 188, in rectangle xy=(x1, y1, x2, y2), fill=fill, outline=outline, width=width TypeError: rectangle() got an unexpected keyword argument 'width'

Kanazawanaoaki commented 4 years ago

僕も種本さんのREADMEを見てやったので、Python3で実行しています。

labelme2voc.pyにはinstance_segmentationのものsemantic_segmentationのものがあるのですが、semantic_segmentationの方で変換すると向きが変わらないみたいです。
semantic_segmentation 382076 instance_segmentation 382076

knorth55 commented 4 years ago

https://github.com/wkentaro/labelme/blob/master/examples/instance_segmentation/labelme2voc.py#L99

img = cv2.imread(img_filename)

とかに変えてみるとどうなりますか?

-- Shingo Kitagawa the University of Tokyo, JSK Lab s-kitagawa@jsk.imi.i.u-tokyo.ac.jp

2020年5月25日(月) 22:45 Naoaki Kanazawa notifications@github.com:

僕も種本さんのREADMEを見てやったので、Python3で実行しています。

labelme2voc.pyにはinstance_segmentationのもの https://github.com/wkentaro/labelme/blob/master/examples/instance_segmentation/labelme2voc.py とsemantic_segmentationのもの https://github.com/wkentaro/labelme/blob/master/examples/semantic_segmentation/labelme2voc.py があるのですが、semantic_segmentationの方で変換すると向きが変わらないみたいです。 semantic_segmentation [image: 382076] https://user-images.githubusercontent.com/38127823/82818153-3dca9580-9ed9-11ea-9273-5a7228fee406.jpg instance_segmentation [image: 382076] https://user-images.githubusercontent.com/38127823/82818167-4327e000-9ed9-11ea-8393-9c654f5fbe71.jpg

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Kanazawanaoaki/cook_eyes/issues/4#issuecomment-633580265, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACG6QXZLXMZNFN62G355PFDRTJY55ANCNFSM4NDLINKA .

Kanazawanaoaki commented 4 years ago

あ、試してみます。とりあえずご報告ですが、semanticの方を真似して、

from labelme import utils

# 中略

img_file = osp.join(osp.dirname(label_file), data['imagePath'])
image_pil = PIL.Image.open(img_file)
image_pil = utils.apply_exif_orientation(image_pil)
img = np.asarray(image_pil)
PIL.Image.fromarray(img).save(out_img_file)

とするとJpegの画像は変換されなくなりました!
382076

MiyabiTane commented 4 years ago

北川さんの方法でも画像のサイズを保つことができました! output_dirに保存する部分のコードはまだ書けていないので金沢くんができているならそれでOKな 気がします!

Kanazawanaoaki commented 4 years ago

@MiyabiTane 何故かimg = cv2.imread(img_file)(https://gist.github.com/Kanazawanaoaki/7140bc0e0d429a9249bce419ace6ed5e#file-instanve_voc_cv-py )にすると色が変になってしまったんだけどそうならなかった?
382076 もしそうなっていないなら僕のは他の部分も変な可能性がある?

MiyabiTane commented 4 years ago

cv2を使った後PILを使うのはどうなんだろうと思ってcv2で保存する方法を探してたところに金沢くんのコメントが来たからその方法は確認してないです、ごめんなさい...。 私の手元でも金沢くんが共有してくれた方を試してみます。

Kanazawanaoaki commented 4 years ago

そうだよね、、 確かOpenCVとPILでRGBの順番が違うみたいな話があった気がするのでそれを直す必要があるんだよね、多分。
問題なさそうなら、とりあえず僕が書いたやつでPRを出して見ようと思います。

MiyabiTane commented 4 years ago

ちょっとまって動かないです

MiyabiTane commented 4 years ago
img_file = osp.join(osp.dirname(label_file), data['imagePath'])
image_pil = PIL.Image.open(img_file)
image_pil = labelme.utils.apply_exif_orientation(image_pil)
img = np.asarray(image_pil)
PIL.Image.fromarray(img).save(out_img_file)

で動きました、書き間違えただけかな?金沢くんの手元でlabelme.がついてるならOKです。逆さまの画像問題も直ってました!

Kanazawanaoaki commented 4 years ago

from labelme import utilsもした?それでもエラーになったのかな?
どっちにしてもそっちの書き方の方が良さそうかな

MiyabiTane commented 4 years ago

あ、それはしてない...。でもわざわざimport labelmeしてるからそっち使った方がいいのかな、と。 ごめんなさいちょっと勘違いしてたどっちでもいいと思います。

MiyabiTane commented 4 years ago

ちなみにpythonで動かないのも問題な気がするのでもしよかったら金沢くんの手元でもpythonで動かすの試してほしいです。

#!/usr/bin/env python

ってことはpython3では動かさない想定のはず...。

Kanazawanaoaki commented 4 years ago
$ python labelme2voc.py annotated/ voc_dataset_instance_test/ --labels labels.txt 
Creating dataset: voc_dataset_instance_test/
class_names: ('_background_', 'potate', 'onion', 'carrot', 'tomato', 'octopus_wiener', 'broccoli', 'flower_carrot', 'rolled_egg', 'fried_chicken', 'lunch_box')
Saved class_names: voc_dataset_instance_test/class_names.txt
Generating dataset from: annotated/382076.json
Traceback (most recent call last):
  File "labelme2voc.py", line 140, in <module>
    main()
  File "labelme2voc.py", line 119, in main
    loc='rb',
  File "/usr/local/lib/python2.7/dist-packages/imgviz/label.py", line 169, in label2rgb
    legend, aabb1, aabb2, fill=(255, 255, 255)
  File "/usr/local/lib/python2.7/dist-packages/imgviz/draw.py", line 188, in rectangle
    xy=(x1, y1, x2, y2), fill=fill, outline=outline, width=width
TypeError: rectangle() got an unexpected keyword argument 'width'

とりあえず試してみただけど、同じエラーっぽい?

MiyabiTane commented 4 years ago

うーん、なるほど。ありがとう。 とりあえずプルリク出しても大丈夫な気がします🎉

knorth55 commented 4 years ago

そうですねcv2.imreadつかったら最後までcv2.imsaveするほうがいいですね。

ちなみに、cv2はBGRの順番で画像を読んでしまうので、こうするとRGB順になります(numpyの逆順にする操作)

img = cv2.imread(img_filename)
# BGR -> RGB
img = img[:, :, ::-1]
knorth55 commented 4 years ago

あと、Pillow >= 5.3.0でないと, width は使えないみたいですね。 python3つかっているなら、pip3 install --user Pillow>=5.3.0とかで解決かな。 python2なら pip install --user Pillow>=5.3.0

knorth55 commented 4 years ago

@Kanazawanaoaki @MiyabiTane PRありがとうございます、デバグお疲れ様です 結局、手軽にやるには手元スクリプトをどう変更するのがいいかな? 大日方くんにも共有してくれると助かります。

@mqcmd196

MiyabiTane commented 4 years ago

ありがとうございます。

python -m pip install --upgrade pip
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Defaulting to user installation because normal site-packages is not writeable
Collecting pip
  Downloading pip-20.1.1-py2.py3-none-any.whl (1.5 MB)
     |████████████████████████████████| 1.5 MB 2.8 MB/s 
Installing collected packages: pip
Successfully installed pip-20.1.1
 pip install --user Pillow>=5.3.0

としてみましたがpython2のサポートが終わってしまっていてうまくいかないようです...。

DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
knorth55 commented 4 years ago

なるほど、じゃあこのlabelmeはpython2ではうごかないみたいですね。 なのでpython3でやってしまいましょう、アノテーションなのでROS関係ないので

Kanazawanaoaki commented 4 years ago

ありがとうございます。

結局、手軽にやるには手元スクリプトをどう変更するのがいいかな?

labelme2voc.pyを使うときに、

wget https://gist.githubusercontent.com/Kanazawanaoaki/7140bc0e0d429a9249bce419ace6ed5e/raw/83d52893fe089515c5f038a28dcd843a3383bbdd/instanvce_voc_utils.py -O labelme2voc.py

としてとってきたlabelme2voc.pyを使っていただくのが良いと思います。

MiyabiTane commented 4 years ago

結局、手軽にやるには手元スクリプトをどう変更するのがいいかな?

これで動くと思います タイミング被っちゃいましたね...。金沢くんのを参考にしてください。 https://github.com/MiyabiTane/HIRO_LunchBox/blob/master/labelme/labelme2voc.py

python3でやってしまいましょう、アノテーションなのでROS関係ないので

了解しました

wkentaro commented 4 years ago

となるとlabelmeのバグっぽいですね

これは、iphoneの姿勢を使うかどうかというところで、単純にimreadしているところは使えていないからおかしく見えるということだと思います。labelme2voc.pyが正しいはず。 ちなみに、UbuntuのGUIだと姿勢は反映されず、Macだとされた気がする。

wkentaro commented 4 years ago

僕も種本さんのREADMEを見てやったので、Python3で実行しています。

これですね。instance_segmentaion/labelme2voc.pyではapply_orientationがされていなかった。 あとUbuntuのGUIでも普通に姿勢反映されていました。

wget https://raw.githubusercontent.com/Kanazawanaoaki/cook_eyes/master/food_detector/food_only_data/very_easy_data/train/382076.jpg
python
>>> import matplotlib.pyplot as plt
>>> plt.imshow(plt.imread("382076.jpg")); plt.show()
xdg-open ./382076.jpg
knorth55 commented 4 years ago

@wkentaro xdg-openも賢いんですね、ぼくは昔他のやつでダメだった記憶がありました。 対応ありがとうございます。

knorth55 commented 4 years ago

@wkentaro

これは、iphoneの姿勢を使うかどうかというところで、単純にimreadしているところは使えていないからおかしく見えるということだと思います。labelme2voc.pyが正しいはず。 ちなみに、UbuntuのGUIだと姿勢は反映されず、Macだとされた気がする。

こういう感じだそうです。 https://github.com/Kanazawanaoaki/cook_eyes/issues/4#issuecomment-633527640 https://github.com/Kanazawanaoaki/cook_eyes/issues/4#issuecomment-633580265 labelmeで表示した画像とlabelme2voc.pyで保存されてる画像が異なっていたみたいです。 自分も確認していないので、わかりませんが

wkentaro commented 4 years ago

このPRでlabelm_draw_json等も含め全て治ったと思います。また起こったら教えてください。 https://github.com/wkentaro/labelme/pull/666

こういう感じだそうです。

labelmeコマンド自体は賢くしたんだけど、labelme2voc.pyの方で漏れがあったみたい。 昔labelmeでこのfeatureをリクエストされたのときはwebcamとかKinectでちゃんとやればいいじゃんとか思っていたけど、コロナでiPhoneを使ってデータ作ったりするようになって役に立ってよかった。

Kanazawanaoaki commented 4 years ago

対応ありがとうございます。とても勉強になりました。

昔labelmeでこのfeatureをリクエストされたのときはwebcamとかKinectでちゃんとやればいいじゃんとか思っていたけど、コロナでiPhoneを使ってデータ作ったりするようになって役に立ってよかった。

そうだったんですね!

解決して頂いたのでこのissueはcloseしたいと思います。

knorth55 commented 4 years ago

ちなみに、ぼくはiphoneで撮った画像で昔おなじことになったときは、スクリプト書いて全画像をcv2.imreadしてcv2.imsaveして上書きしました。 乱暴なやりかたですがexif情報が消えるので解決します。