Youtubeでも活動中

チャンネル登録してくれたら喜びます。

このボタンで簡単にチャンネル登録!

RaspberryPiの最新OS(Bullseye)でカメラが認識しない問題【解決方法】

RaspberryPi(ラズパイ)

この記事を書いている2023年1月末時点での、
最新のRaspberryPi OSはbullseye(ブルズアイ)です。

おそらく今年あたり次のOSがリリースされるようですが、
現行のBullseyeでも情報が少なくてカメラ接続に手間取った話をします。

「RaspberryPiでカメラを使うなんて、
設定でカメラをONにして終わりでしょ?」

なんて思うじゃないですか。
たしかに一つ前のOSのBusterだったらそれでよかったんです。

最新のBullseyeだとひと手間必要なんです…その話をします。

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

転職に成功して現在は超大手企業でシステム系の開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

まずはRaspberryPiに正しくカメラを接続する。

まずはハード的に正しく接続されていないと、
そもそもRaspbrryPi側で認識されません。

いくら正しい設定にしたところで、
物理的につながっていないものを使えませんからね…

わたしが今回用意したカメラについて。

今回ご用意したカメラはこちら。

camera-for-raspberrypi
今回用意したRaspberryPi用のカメラ。純正ではない…

Amazonで購入したお安めのカメラです。
RaspberryPi純正のカメラでもよかったのですが、
貧乏性なのでお安いサードパーティー製を選びました。

ケース付きなので、撮影時カメラの位置を固定できるのも
グッドなポイントですね。

具体的にどうやってつなげるか?

さて、接続方法に戻りましょう。
この部分がポイントなのですが、
この銀色の膜のようなものを、

camera-cable-connector
カメラのケーブルの接続端子部分。

RaspberryPiのこの金属部分と接続するわけです。

raspberrypi-camera-connector
RaspberryPi側のカメラのコネクタの内部を見てみると、右側に接続用のピンが並んでいる。

注意点ですが、カメラの接続部はピンとピンの距離が短いので、
基本的にはRaspberryPiの電源は完全にOFFしてください。
ACアダプターも抜いてください。
ショートして最悪RaspberryPi本体がやられます。

注意点はこれくらいして、本題に戻ります。

まずはカメラを接続する端子ですが、
基板上に、CAMERAと印字されいるほうです。
似たようなというか同じ形状の端子で、
DISPLAYも存在します。

raspberrypi-connectors
画像の右側がディスプレイ用で、左側がカメラ用。基板上に印字されている。

DISPLAYと印字されているほうにカメラを接続しても
永遠にカメラは使えないので注意しましょう。

接続する端子がわかったところで、
接続部にこのままケーブルを差し込みたくなりますが、
ただ力任せにこの状態でケーブルを差し込んでもダメです。

camera-connector-closing
RaspberryPiのカメラ用端子が閉まっている状態。このままでは刺さらない。

まずのプラスチックでできた耳のようなものを
引き上げてあげる必要があります。

camera-connector-opening
RaspberryPiのカメラ接続部を解放した状態。これでケーブルを差し込める。

引き上げた状態でカメラのケーブルを差し込んで、

camera-inserting
カメラ接続部にケーブルを差し込んだ状態。銀色の端子がギリギリ見えるくらいのところまで深く差し込む。

しっかり奥まで刺さったことを確認して、
最後に耳を押し下げて完了です。

camera-insert-comp
最後にしっかり耳の部分を押し込んで接続完了。

ここまで来たらACアダプターは接続して大丈夫です。

RaspberryPiの設定でカメラの使用を許可する。

この内容はいろんなところで紹介されていますので、
ちょっといまさら感がありますが解説しておきます。

ちなみにこのカメラの使用を許可する手順ですが、
ひとつ前のOSのbusterでも全く同じことをします。

ですから情報としては結構出てきます。

それでは、具体的に何をするのか解説しましょう。

RaspberryPiの設定を開く。

まずはRaspberryPiのターミナルで、

sudo raspi-config

と打ち込んでEnterを押しましょう。

RaspberryPiのConfig画面を出すコマンド。

すると、このような設定画面が表示されます。
この中の上から3つ目。Interface Optionsを選択します。
※キーボードの上下キーでしか操作できませんので注意が必要です。

3番のInterface Optionsを選択する。

その後、I1のLegacy Cameraを選択します。

I1のLegacy cameraを選択する。

すると、カメラを使えるようにしますか?
と聞かれますので<はい>を選択します。

カメラを使えるようにするか聞かれるので、はいを選択する。

その後、使えるようにしたと表示されます。
このまま了解を押すと、再起動を促されるので、それに従って
再起動させましょう。

設定変更が完了したことを知らせる画面。

busterまでのOSであればこれで終了です。
が、まだやることはあります…

カメラが接続されているか確認する。※ここでは接続されない。

さて、物理的にカメラが接続されて、
RaspberryPiの本体側でカメラの使用許可を出しました。

ひとつ前のOSのbusterではこれで終わりだったのですが、
最新版のOSのbullseyeでは一味違います。

いったんここで接続されているか確認してみましょう。

カメラが正しく接続されているか確認する方法。

確認するには、このコマンドをターミナルで打ち込みます。

vcgencmd get_camera

このコマンドを打ち込むことで、
RaspberryPi側で正しくカメラが認識されているか確認することができます。

ひとつ前のbusterとの違い。

この結果は、BusterとBullseyeで異なります。
Busterの場合は、

supported=0or1 detected=0or1

と表示されますが、
Bullseyeはこうなります。

vcgencmd get_cameraした結果。

libcamera interfacesという項目が増えます。
これは後ほど説明しますが、Bullseyeから登場しました。

supportedとdetectedの説明を簡単にしておくと、
supportedは先ほどカメラの有効化でONになると1になります。
detectedはカメラが接続されているば1になります。

「あれ、画像だとdetected=0だから接続できないじゃん。」
鋭いですね。ただ、これはそれでいいんです。

なぜなら、このdetectedはbusterまでのOSで認識していたもので、
bullseyeからは接続されていようがいまいが、0になります。
とんでもなくわかりにくいですよね。

【本題】改めて接続するためにする手順【解決方法】

さて、ここまででもbullseyeの特殊性がわかってもらえたと思いますが、
このままではカメラは使えません。

ここからは、bullseyeでカメラを使えるようにする手順です。

カメラに使用されているセンサーの型番を調べる。

カメラには、レンズと、イメージャーと言われる画像センサーが
内部に組み込まれています。撮像素子なんて言われたりもします。

そのセンサーをまずは調べる必要があります。
例えば、今回用意したカメラは、型番がGeeekPi 5MP 1080Pとなっています。

さて、ここからセンサーの型番が乗っていればよかったのですが、
この商品ページには、センサーの型番は記載されていません。

メーカー名と、5MP1080Pを頼りにググると、このように、
Omnivision5647が搭載されているとの記載が見つかります。

omnivision
このカメラに搭載されているセンサーは、Omnivision5647だと判明。

センサーと言えば天下のSONYがメジャーです。
SONYの場合は、IMX○○という感じの型番なので一目見ればわかります。

Omnivisionについて少し調べてみましたが、
車載カメラやスマホなどで結構なシェアを持っているようでした。

分野によってはSONYを超えるシェアを持っているんです…
全然知らなかった。

記事は直接関係ないですが、
この記事内にOmnivisionのシェアが記載されているグラフがあります。
↓↓↓↓

Yole、2022年のCMOSイメージセンサ市場見通しを下方修正
Yole Groupは、「2022 Yole Group Market Monitor Tour in Japan」を開催。第3四半期にCMOSイメージセンサ(CIS)市場予測の下方修正を行ったことなどが報告された。

センサーの型番を設定ファイルに追記する。

前の章でセンサーの型番が必要と言いましたが、
実はこれRaspberryPi側で型番を記載する必要があるんです…めんどくさ。
もちろん、このカメラ以外、厳密には、
他のセンサーが乗ったカメラを使いたい場合は同じ作業が必要です。…めんどくさ。

それでは、どこに記載するかの説明をしましょう。

raspberryPiのターミナルで、
このように打ち込んでください。

sudo nano /boot/config.tex

RaspberryPiの設定ファイルを開いて編集することが可能です。
開いたら、一番下のとこをこんな感じにしてみてください。

dtoverlayにov5647を追加して使えるようにする。

重要なのは、dtoveray=というやつです。

ラズベリーパイの公式ページで、
どのセンサーはどういう風に記載してね。という表があります。

raspberrypi公式より

Omnivisionは省略されてovと記載されています。
ほかにもIMX系列(SONY製)も設定することで使用可能です。

config.txtに上記のov5647を追記したら、^Xして終了(保存も)して、
再起動しましょう。

最後に動作確認して終了。

さて、ここまで来たらやっとカメラが使えます。
(正確には、Omnivisionの5647を積んだカメラが使えます)

では実際に撮影してみましょう。

コマンドはこうです。

libcamera-jpeg -n -o test.jpg

このコマンドを打つと、
カメラで1枚写真を撮ります。

ピントが全然あってない…ケーブルの長さの関係でそこまで離せなかった。

保存されるところは、homeフォルダ内の、
ドキュメントや画像フォルダが入っているフォルダです。

ここのフォルダの名前は人それぞれですので、
ドキュメントなどが入っているフォルダだと思ってもらえれば大丈夫です。

実はお試しとして、
コンソールソフトでいうところの、Hello,world!が用意されています。

それが、このコマンドです。

libcamera-hello

これが正しく実行されるはずなのですが、
私の場合、error19が出ました。こんなの↓↓

terminate called after throwing an instance of 'std::runtime_error'
  what():  failed to import fd 19

ちょっとこの話は別の記事で解決策も含めてご紹介します。

結局なんでこんなにめんどくさくなったか?

めんどくさくなった原因ですが、
単純に言って、libcameraというものが実装されたからです。

それに加えて、2021年にBullseyeと同時に実装されたため、
比較的最近の情報が無いわけですね…

この情報が無い。ということについては以前の記事で紹介しています。
↓↓以前の記事↓↓

今回のまとめ

今回は記事執筆時点での最新OSであるBullseyeで
カメラの接続から、画像を保存するところまでご紹介しました。

情報が少ないので、困っている人のためになれば幸いです。

コメント

'}},vars:{discoveredBrushes:null,highlighters:{}},brushes:{},regexLib:{multiLineCComments:XRegExp("/\\*.*?\\*/","gs"),singleLineCComments:/\/\/.*$/gm,singleLinePerlComments:/#.*$/gm,doubleQuotedString:/"([^\\"\n]|\\.)*"/g,singleQuotedString:/'([^\\'\n]|\\.)*'/g,multiLineDoubleQuotedString:XRegExp('"([^\\\\"]|\\\\.)*"',"gs"),multiLineSingleQuotedString:XRegExp("'([^\\\\']|\\\\.)*'","gs"),xmlComments:XRegExp("(<|<)!--.*?--(>|>)","gs"),url:/https?:\/\/[\w-.\/?%&=:@;#]*/g,phpScriptTags:{left:/(<|<)\?(?:=|php)?/g,right:/\?(>|>)/g,eof:!0},aspScriptTags:{left:/(<|<)%=?/g,right:/%(>|>)/g},scriptScriptTags:{left:/(<|<)\s*script.*?(>|>)/gi,right:/(<|<)\/\s*script\s*(>|>)/gi}},toolbar:{getHtml:function(e){function t(e,t){return B.toolbar.getButtonHtml(e,t,B.config.strings[t])}for(var n='
',r=B.toolbar.items,i=r.list,a=0,l=i.length;l>a;a++)n+=(r[i[a]].getHtml||t)(e,i[a]);return n+=""},getButtonHtml:function(t,n,r){return n=e(n),''+e(r)+""},handler:function(e){function t(e){var t=RegExp(e+"_(\\w+)"),n=t.exec(r);return n?n[1]:null}var n=e.target,r=n.className||"",i=s(g(n,".syntaxhighlighter").id),a=t("command");i&&a&&B.toolbar.items[a].execute(i),e.preventDefault()},items:{list:["expandSource","help"],expandSource:{getHtml:function(e){if(1!=e.getParam("collapse"))return"";var t=e.getParam("title");return B.toolbar.getButtonHtml(e,"expandSource",t?t:B.config.strings.expandSource)},execute:function(e){var t=o(e.id);r(t,"collapsed")}},help:{execute:function(){var e=x("","_blank",500,250,"scrollbars=0"),t=e.document;t.write(B.config.strings.aboutDialog),t.close(),e.focus()}}}},findElements:function(e,t){var n=t?[t]:i(document.getElementsByTagName(B.config.tagName)),r=B.config,a=[];if(r.useScriptTags&&(n=n.concat(A())),0===n.length)return a;for(var l=0,s=n.length;s>l;l++){var o={target:n[l],params:p(e,E(n[l].className))};null!=o.params.brush&&a.push(o)}return a},highlight:function(e,t){var n=this.findElements(e,t),r="innerHTML",i=null,a=B.config;if(0!==n.length)for(var l=0,s=n.length;s>l;l++){var o,t=n[l],u=t.target,c=t.params,g=c.brush;if(null!=g){if("true"==c["html-script"]||1==B.defaults["html-script"])i=new B.HtmlScript(g),g="htmlscript";else{var h=b(g);if(!h)continue;i=new h}o=u[r],a.useScriptTags&&(o=M(o)),""!=(u.title||"")&&(c.title=u.title),c.brush=g,i.init(c),t=i.getDiv(o),""!=(u.id||"")&&(t.id=u.id),u.parentNode.replaceChild(t,u)}}},all:function(e){m(window,"load",function(){B.highlight(e)})}};return B.Match=function(e,t,n){this.value=e,this.index=t,this.length=e.length,this.css=n,this.brushName=null},B.Match.prototype.toString=function(){return this.value},B.HtmlScript=function(e){function t(e,t){for(var n=0,r=e.length;r>n;n++)e[n].index+=t}function n(e){for(var n,a=e.code,l=[],s=r.regexList,o=e.index+e.left.length,u=r.htmlScript,c=0,g=s.length;g>c;c++)n=L(a,s[c]),t(n,o),l=l.concat(n);null!=u.left&&null!=e.left&&(n=L(e.left,u.left),t(n,e.index),l=l.concat(n)),null!=u.right&&null!=e.right&&(n=L(e.right,u.right),t(n,e.index+e[0].lastIndexOf(e.right)),l=l.concat(n));for(var h=0,g=l.length;g>h;h++)l[h].brushName=i.brushName;return l}var r,i=b(e),a=new B.brushes.Xml,l=this,s="getDiv getHtml init".split(" ");if(null!=i){r=new i;for(var o=0,u=s.length;u>o;o++)(function(){var e=s[o];l[e]=function(){return a[e].apply(a,arguments)}})();return null==r.htmlScript?(v(B.config.strings.brushNotHtmlScript+e),void 0):(a.regexList.push({regex:r.htmlScript.code,func:n}),void 0)}},B.Highlighter=function(){},B.Highlighter.prototype={getParam:function(e,t){var n=this.params[e];return d(null==n?t:n)},create:function(e){return document.createElement(e)},findMatches:function(e,t){var n=[];if(null!=e)for(var r=0,i=e.length;i>r;r++)"object"==typeof e[r]&&(n=n.concat(L(t,e[r])));return this.removeNestedMatches(n.sort(k))},removeNestedMatches:function(e){for(var t=0,n=e.length;n>t;t++)if(null!==e[t])for(var r=e[t],i=r.index+r.length,a=t+1,n=e.length;n>a&&null!==e[t];a++){var l=e[a];if(null!==l){if(l.index>i)break;l.index==r.index&&l.length>r.length?e[t]=null:l.index>=r.index&&i>l.index&&(e[a]=null)}}return e},figureOutLineNumbers:function(e){var t=[],n=parseInt(this.getParam("first-line"));return y(e,function(e,r){t.push(r+n)}),t},isLineHighlighted:function(e){var t=this.getParam("highlight",[]);return"object"!=typeof t&&null==t.push&&(t=[t]),-1!=h(t,""+e)},getLineHtml:function(e,t,n){var r=["line","number"+t,"index"+e,"alt"+(""+(0==t%2?1:2))];return this.isLineHighlighted(t)&&r.push("highlighted"),0==t&&r.push("break"),'
'+n+""},getLineNumbersHtml:function(e,t){var n="",r=a(e).length,i=parseInt(this.getParam("first-line")),l=this.getParam("pad-line-numbers");1==l?l=(""+(i+r-1)).length:1==isNaN(l)&&(l=0);for(var s=0;r>s;s++){var o=t?t[s]:i+s,e=0==o?B.config.space:S(o,l);n+=this.getLineHtml(s,o,e)}return n},getCodeLinesHtml:function(e,t){e=C(e);for(var n=a(e),r=(this.getParam("pad-line-numbers"),parseInt(this.getParam("first-line"))),e="",i=this.getParam("brush"),l=0,s=n.length;s>l;l++){var o=n[l],u=/^( |\s)+/.exec(o),c=null,g=t?t[l]:r+l;null!=u&&(c=""+u[0],o=o.substr(c.length),c=c.replace(" ",B.config.space)),o=C(o),0==o.length&&(o=B.config.space),e+=this.getLineHtml(l,g,(null!=c?''+c+"":"")+o)}return e},getTitleHtml:function(t){return t?""+e(t)+"":""},getMatchesHtml:function(e,t){function n(e){var t=e?e.brushName||a:a;return t?t+" ":""}for(var r=0,i="",a=this.getParam("brush",""),l=0,s=t.length;s>l;l++){var o,u=t[l];null!==u&&0!==u.length&&(o=n(u),i+=N(e.substr(r,u.index-r),o+"plain")+N(u.value,o+u.css),r=u.index+u.length+(u.offset||0))}return i+=N(e.substr(r),n()+"plain")},getHtml:function(t){var n,r,i,a="",s=["syntaxhighlighter"];return 1==this.getParam("light")&&(this.params.toolbar=this.params.gutter=!1),className="syntaxhighlighter",1==this.getParam("collapse")&&s.push("collapsed"),0==(gutter=this.getParam("gutter"))&&s.push("nogutter"),s.push(this.getParam("class-name")),s.push(this.getParam("brush")),t=w(t).replace(/\r/g," "),n=this.getParam("tab-size"),t=1==this.getParam("smart-tabs")?R(t,n):H(t,n),this.getParam("unindent")&&(t=P(t)),gutter&&(i=this.figureOutLineNumbers(t)),r=this.findMatches(this.regexList,t),a=this.getMatchesHtml(t,r),a=this.getCodeLinesHtml(a,i),this.getParam("auto-links")&&(a=I(a)),"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.match(/MSIE/)&&s.push("ie"),a='
'+(this.getParam("toolbar")?B.toolbar.getHtml(this):"")+''+this.getTitleHtml(this.getParam("title"))+""+""+(gutter?'
'+this.getLineNumbersHtml(t)+"":"")+''+'
'+a+""+""+""+""+""+""},getDiv:function(e){null===e&&(e=""),this.code=e;var t=this.create("div");return t.innerHTML=this.getHtml(e),this.getParam("toolbar")&&m(c(t,".toolbar"),"click",B.toolbar.handler),this.getParam("quick-code")&&m(c(t,".code"),"dblclick",X),t},init:function(e){this.id=f(),u(this),this.params=p(B.defaults,e||{}),1==this.getParam("light")&&(this.params.toolbar=this.params.gutter=!1)},getKeywords:function(e){return e=e.replace(/^\s+|\s+$/g,"").replace(/\s+/g,"|"),"\\b(?:"+e+")\\b"},forHtmlScript:function(e){var t={end:e.right.source};e.eof&&(t.end="(?:(?:"+t.end+")|$)"),this.htmlScript={left:{regex:e.left,css:"script"},right:{regex:e.right,css:"script"},code:XRegExp("(?"+e.left.source+")"+"(?.*?)"+"(?"+t.end+")","sgi")}}},B}();"undefined"!=typeof exports?exports.SyntaxHighlighter=SyntaxHighlighter:null;
タイトルとURLをコピーしました