Closed Kanazawanaoaki closed 4 years ago
そもそもの画像を反転させて、新しくアノテーションをすると上手くアノテーション出来ているように思える。
very_easy_data_kai/train/382076.jpg
labelme --labels labels.txt very_easy_data_kai/train/382076.jpg
labelme_draw_label_png very_easy_data_kai_datasets/train/SegmentationClassPNG/382076.png
以前学習させたネットワークをtrainの予測を見て確認した時にも、横長の画像はそれなりに学習できていそうなのに、縦長の画像は上手く言っていないという事があった。それもこれが原因だったのかも。これからは横長の写真を使うか縦長の場合は回転させて使うのが良さそう。
画像をiphoneとかでとっていますか? iphoneで縦長の画像をとっている場合には、たまに画像の表示は縦長なのに画像のデータとしては横長になっていることがあります。 そうなるとlabelme_draw_みたいなプログラムで、横長と認識して可視化している可能性があります。 cv2などで画像をreadしてshapeなどをみてみると良いかと思います。
img = cv2.imread(path)
# shape = (Height, Width, Channel)
print(img.shape)
そうなっているとアノテーションもかなりおかしなことになりますね。 アノテーションが縦長画像に対して行われているのに、画像が横長としてロードされていると意味がないので そうなると学習も上手くいかないでしょう。 データセットの画像について詳しく見る必要がありそうですね
ありがとうございます。
画像はiphoneでとっています。 なるほどそういうことだったんですね。
データセットの画像について確認してみようと思います。
この問題に関連して、画像が逆さまになってしまうという問題を発見しました。
iphoneで写真を撮る時はホームボタンが右側にくるようにし、外カメラで撮影するとこの問題が回避できる気がします。
iphoneで写真を撮った後に回転させてからPCに送ってもdlboxでは最初に撮ったときの情報で処理されるというのと、内カメラで撮った写真は逆さまになるのではないかというのが私の考えです。(確信はないです。)
下の図では上の画像がアノテーションしたもの、下の画像がtensorboardで見たものです。 ground-truth(下の画像の右側)の画像からアノテーションの情報と画像がずれていることがわかります。
@MiyabiTane ちなみに、iPhoneでみたときはtensorboardのほうが正しいですか?(つまり上下逆さまにはiPhoneではなってないんですよね) labelmeでこの画像表示した時の画面キャプチャもみてみたいです。
iPhoneで送った後、PC上で向きの操作などは一切していないです。
そして、すみません。画像(上のコメントの、上の画像がアノテーションしたもの、の方)を見て向き的に自分でiphone上で回転させたものだろうと思っていたのですが、今iphoneで編集ボタンを押すとオリジナルに戻す、という表示が出ないのでiphoneで撮ったままの画像のようです。
説明がわかりにくくて申し訳ないのですが、つまり言うと、iphoneで撮影した後、iphone上でもPC上でも、何の回転も加えていないはずだと言うことです。
ただ、普通写真をとると下の画像のような向きになるはずで、なぜ逆さまになっているのかは撮った本人もわかっていないです。。。
labelme上の向きもiphoneと同じなので、違っているのはtensorboardだけだと思います。
アノテーションをしたフォルダの画像を見ると正しい向き(?)になっていそうですが、
(https://github.com/MiyabiTane/HIRO_LunchBox/blob/master/labelme/okazu_50/train/IMG_5765.JPG )
VOC形式にした後のJPEGImages内の画像を見ると反転されてしまっているみたいですかね?
(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
を見るとセグメンテーションは反転される前の画像の向きになっているのでそこでラベル付けのズレが生じているのが問題なのでしょうか。
金沢くんの最初の人参もデータセットでは正しく縦になってたんだっけ?
となるとlabelmeのバグっぽいですね cc. @wkentaro
僕の最初の人参の画像(iPhoneで縦長で撮影して回転など編集は一切行っていない)場合はアノテーションした時の画像が縦長、
(https://github.com/Kanazawanaoaki/cook_eyes/blob/master/food_detector/food_only_data/very_easy_data/train/382076.jpg )
VOC形式に変換した時のJPEGImages内の画像が横長、
(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
で確認したときは縦長画像に対してのアノテーションが横長に無理やり変換されているようになっています。
>>> import cv2
>>> img = cv2.imread("382076.jpg")
>>> print(img.shape)
(4032, 3024, 3)
なのでOpenCVで読んでも縦長に認識されているようですが、iPhoneで撮影した画像の場合labelmeのVOC変換を行う際にJPEGImagesが回転や反転して、セグメンテーションとずれてしまう事があるみたいですね。
なるほど、おもしろいですね つまりlabelmeの読み込みと保存で形が変わってしまっているのですね PRチャンスですね。
あ、ほんとだ、気づかなかった...。金沢くん指摘ありがとう! これが直ればiphoneの写真の撮り方や回転編集の有無を考慮しなくてよくなりそうですね。
直せたらPRですね、時間つくって頑張ってみます。
ちなみに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 .
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
僕も種本さんのREADMEを見てやったので、Python3で実行しています。
labelme2voc.pyにはinstance_segmentationのものとsemantic_segmentationのものがあるのですが、semantic_segmentationの方で変換すると向きが変わらないみたいです。
semantic_segmentation
instance_segmentation
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 .
あ、試してみます。とりあえずご報告ですが、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の画像は変換されなくなりました!
北川さんの方法でも画像のサイズを保つことができました! output_dirに保存する部分のコードはまだ書けていないので金沢くんができているならそれでOKな 気がします!
@MiyabiTane 何故かimg = cv2.imread(img_file)
(https://gist.github.com/Kanazawanaoaki/7140bc0e0d429a9249bce419ace6ed5e#file-instanve_voc_cv-py )にすると色が変になってしまったんだけどそうならなかった?
もしそうなっていないなら僕のは他の部分も変な可能性がある?
cv2を使った後PILを使うのはどうなんだろうと思ってcv2で保存する方法を探してたところに金沢くんのコメントが来たからその方法は確認してないです、ごめんなさい...。 私の手元でも金沢くんが共有してくれた方を試してみます。
そうだよね、、 確かOpenCVとPILでRGBの順番が違うみたいな話があった気がするのでそれを直す必要があるんだよね、多分。
問題なさそうなら、とりあえず僕が書いたやつでPRを出して見ようと思います。
ちょっとまって動かないです
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です。逆さまの画像問題も直ってました!
from labelme import utils
もした?それでもエラーになったのかな?
どっちにしてもそっちの書き方の方が良さそうかな
あ、それはしてない...。でもわざわざimport labelmeしてるからそっち使った方がいいのかな、と。
ごめんなさいちょっと勘違いしてたどっちでもいいと思います。
ちなみにpythonで動かないのも問題な気がするのでもしよかったら金沢くんの手元でもpythonで動かすの試してほしいです。
#!/usr/bin/env python
ってことはpython3では動かさない想定のはず...。
$ 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'
とりあえず試してみただけど、同じエラーっぽい?
うーん、なるほど。ありがとう。 とりあえずプルリク出しても大丈夫な気がします🎉
そうですねcv2.imreadつかったら最後までcv2.imsaveするほうがいいですね。
ちなみに、cv2はBGRの順番で画像を読んでしまうので、こうするとRGB順になります(numpyの逆順にする操作)
img = cv2.imread(img_filename)
# BGR -> RGB
img = img[:, :, ::-1]
あと、Pillow >= 5.3.0
でないと, width
は使えないみたいですね。
python3つかっているなら、pip3 install --user Pillow>=5.3.0
とかで解決かな。
python2なら pip install --user Pillow>=5.3.0
@Kanazawanaoaki @MiyabiTane PRありがとうございます、デバグお疲れ様です 結局、手軽にやるには手元スクリプトをどう変更するのがいいかな? 大日方くんにも共有してくれると助かります。
@mqcmd196
ありがとうございます。
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
なるほど、じゃあこのlabelme
はpython2ではうごかないみたいですね。
なのでpython3でやってしまいましょう、アノテーションなのでROS関係ないので
ありがとうございます。
結局、手軽にやるには手元スクリプトをどう変更するのがいいかな?
labelme2voc.pyを使うときに、
wget https://gist.githubusercontent.com/Kanazawanaoaki/7140bc0e0d429a9249bce419ace6ed5e/raw/83d52893fe089515c5f038a28dcd843a3383bbdd/instanvce_voc_utils.py -O labelme2voc.py
としてとってきたlabelme2voc.pyを使っていただくのが良いと思います。
結局、手軽にやるには手元スクリプトをどう変更するのがいいかな?
これで動くと思います
タイミング被っちゃいましたね...。金沢くんのを参考にしてください。
https://github.com/MiyabiTane/HIRO_LunchBox/blob/master/labelme/labelme2voc.py
python3でやってしまいましょう、アノテーションなのでROS関係ないので
了解しました
となるとlabelmeのバグっぽいですね
これは、iphoneの姿勢を使うかどうかというところで、単純にimreadしているところは使えていないからおかしく見えるということだと思います。labelme2voc.pyが正しいはず。 ちなみに、UbuntuのGUIだと姿勢は反映されず、Macだとされた気がする。
僕も種本さんの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
@wkentaro xdg-open
も賢いんですね、ぼくは昔他のやつでダメだった記憶がありました。
対応ありがとうございます。
@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で保存されてる画像が異なっていたみたいです。 自分も確認していないので、わかりませんが
このPRでlabelm_draw_json等も含め全て治ったと思います。また起こったら教えてください。 https://github.com/wkentaro/labelme/pull/666
こういう感じだそうです。
labelmeコマンド自体は賢くしたんだけど、labelme2voc.pyの方で漏れがあったみたい。 昔labelmeでこのfeatureをリクエストされたのときはwebcamとかKinectでちゃんとやればいいじゃんとか思っていたけど、コロナでiPhoneを使ってデータ作ったりするようになって役に立ってよかった。
対応ありがとうございます。とても勉強になりました。
昔labelmeでこのfeatureをリクエストされたのときはwebcamとかKinectでちゃんとやればいいじゃんとか思っていたけど、コロナでiPhoneを使ってデータ作ったりするようになって役に立ってよかった。
そうだったんですね!
解決して頂いたのでこのissueはcloseしたいと思います。
ちなみに、ぼくはiphoneで撮った画像で昔おなじことになったときは、スクリプト書いて全画像をcv2.imreadしてcv2.imsaveして上書きしました。 乱暴なやりかたですがexif情報が消えるので解決します。
labelmeによってアノテーションを行っているが、縦長の画像に対してのアノテーションが上手く言っていない可能性がある。
very_easy_data/train/382076.jpg