00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <QTimer>
00026
00027 #include <QVImage>
00028 #include <qvio/qvcameraworker.h>
00029 #include <qvip/qvipp/qvipp.h>
00030
00031 #define DEFAULT_IMAGE_SIZE 128
00032
00033 QVCameraWorker::QVCameraWorker(QString name): QVWorker(name)
00034 {
00035
00036 addProperty<bool>("NoLoop", inputFlag, FALSE,"If the camera should be opened in no loop mode");
00037 addProperty<QString>("URL", inputFlag, QString(""),"URL of the video source to read");
00038 addProperty<int>("Cols", inputFlag, 0, "Suggested number of columns of the video");
00039 addProperty<int>("Rows", inputFlag, 0, "Suggested number of rows of the video");
00040
00041
00042 addProperty<bool>("RealTime", inputFlag|guiInvisible, FALSE, "If the camera should be opened in real time mode");
00043
00044
00045 addProperty<bool>("Opened", outputFlag, FALSE, "If the camera is correctly opened and working");
00046 addProperty<int>("FPS", outputFlag, 0, "FPS of the video");
00047 addProperty<int>("Frames", outputFlag, 0, "Number of read frames");
00048 addProperty<int>("ColsR", outputFlag, 0, "Actual number of columns of the video");
00049 addProperty<int>("RowsR", outputFlag, 0, "Actual number of rows of the video");
00050
00051
00052 addProperty< QVImage<uChar,3> >("RGB image", outputFlag, QVImage<uChar,3>(), "Last grabbed RGB image");
00053 addProperty< QVImage<uChar,1> >("Y channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed Y channel image");
00054 addProperty< QVImage<uChar,1> >("U channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed U channel image");
00055 addProperty< QVImage<uChar,1> >("V channel image",outputFlag, QVImage<uChar,1>(), "Last grabbed V channel image");
00056
00057
00058 addTrigger("Reopen");
00059
00060
00061 imageY = QVImage<uChar>(DEFAULT_IMAGE_SIZE,DEFAULT_IMAGE_SIZE,DEFAULT_IMAGE_SIZE);
00062 imageU = QVImage<uChar>(DEFAULT_IMAGE_SIZE/2,DEFAULT_IMAGE_SIZE/2,DEFAULT_IMAGE_SIZE/2);
00063 imageV = QVImage<uChar>(DEFAULT_IMAGE_SIZE/2,DEFAULT_IMAGE_SIZE/2,DEFAULT_IMAGE_SIZE/2);
00064 Set(128,imageY);
00065 Set(128,imageU);
00066 Set(128,imageV);
00067 setPropertyValue< QVImage<uChar, 1> >("Y channel image", imageY);
00068 setPropertyValue< QVImage<uChar, 1> >("U channel image", imageU);
00069 setPropertyValue< QVImage<uChar, 1> >("V channel image", imageV);
00070 QVImage<uChar, 3> imageRGB(DEFAULT_IMAGE_SIZE,DEFAULT_IMAGE_SIZE);
00071 YUV420ToRGB(imageY, imageU, imageV, imageRGB);
00072 setPropertyValue< QVImage<uChar, 3> >("RGB image", imageRGB);
00073
00074 }
00075
00076 QVCameraWorker::~QVCameraWorker()
00077 {
00078
00079
00080 }
00081
00082 static inline int iRoundUp(int a, int b) {
00083 return (a % b == 0) ? a : b*(a / b + 1) ;
00084 }
00085
00086 void QVCameraWorker::tryOpeningCam()
00087 {
00088
00089 int cols, rows, fps;
00090
00091
00092 realTime = getPropertyValue<bool>("RealTime");
00093 noLoop = getPropertyValue<bool>("NoLoop");
00094 urlName = getPropertyValue<QString>("URL");
00095 cols = getPropertyValue<int>("Cols");
00096 rows = getPropertyValue<int>("Rows");
00097
00098
00099 if(this->openCam(urlName,cols,rows,fps))
00100 {
00101 setPropertyValue<bool>("Opened",TRUE);
00102 setPropertyValue<int>("ColsR",cols);
00103 setPropertyValue<int>("RowsR",rows);
00104 setPropertyValue<int>("FPS",fps);
00105 setPropertyValue<int>("Frames",0);
00106 imageY = QVImage<uChar>(cols, rows, iRoundUp(cols,8));
00107 imageU = QVImage<uChar>(cols/2, rows/2, iRoundUp(cols/2,8));
00108 imageV = QVImage<uChar>(cols/2, rows/2, iRoundUp(cols/2,8));
00109 setPropertyValue< QVImage<uChar, 1> >("Y channel image", imageY);
00110 setPropertyValue< QVImage<uChar, 1> >("U channel image", imageU);
00111 setPropertyValue< QVImage<uChar, 1> >("V channel image", imageV);
00112 setPropertyValue< QVImage<uChar, 3> >("RGB image", QVImage<uChar,3>(cols, rows, iRoundUp(3*cols,8)));
00113 newGrabbedFrame = FALSE;
00114
00115
00116
00117
00118 if (realTime)
00119 QTimer::singleShot(0, this, SLOT(grabFrame()));
00120
00121
00122 unPause();
00123 }
00124 else
00125 resetCameraWorker();
00126 }
00127
00128 void QVCameraWorker::resetCameraWorker()
00129 {
00130
00131
00132 flush_pending_images = TRUE;
00133 while(qApp->hasPendingEvents ()) qApp->processEvents();
00134 flush_pending_images = FALSE;
00135
00136
00137 this->closeCam();
00138
00139
00140 setPropertyValue<bool>("Opened",FALSE);
00141 setPropertyValue<int>("FPS",0);
00142 setPropertyValue<int>("Frames",0);
00143
00144
00145 stop();
00146 }
00147
00148
00149 bool QVCameraWorker::linkUnspecifiedOutputProperty(QVPropertyContainer *destinyContainer, QString destinyPropertyName)
00150 {
00151
00152 LinkType linkType = getPropertyValue<bool>("RealTime") ? AsynchronousLink : SynchronousLink;
00153
00154
00155 if (destinyContainer->isType< QVImage<uChar, 3> >(destinyPropertyName))
00156 return QVWorker::linkProperty("RGB image", destinyContainer, destinyPropertyName, linkType);
00157 else if (destinyContainer->isType< QVImage<uChar, 1> >(destinyPropertyName))
00158 return QVWorker::linkProperty("Y channel image", destinyContainer, destinyPropertyName, linkType);
00159 else
00160 {
00161 qWarning() << "QVCameraWorker::linkUnspecifiedOutputProperty(): error, can't link property " << qPrintable(destinyPropertyName) << ".";
00162 return false;
00163 }
00164 }
00165
00166 bool QVCameraWorker::linkUnspecifiedOutputProperty(QVPropertyContainer *destinyContainer, QString destinyPropertyName1, QString destinyPropertyName2, QString destinyPropertyName3)
00167 {
00168
00169 LinkType linkType = getPropertyValue<bool>("RealTime") ? AsynchronousLink : SynchronousLink;
00170
00171 bool ok = TRUE;
00172
00173
00174 if (destinyContainer->isType< QVImage<uChar, 1> >(destinyPropertyName1))
00175 if(not QVWorker::linkProperty("Y channel image", destinyContainer, destinyPropertyName1, linkType))
00176 {
00177 ok = FALSE;
00178 qWarning() << "QVCameraWorker::linkUnspecifiedOutputProperty(): error, can't link Y property " << qPrintable(destinyPropertyName1) ;
00179 }
00180 if (destinyContainer->isType< QVImage<uChar, 1> >(destinyPropertyName2))
00181 if(not QVWorker::linkProperty("U channel image", destinyContainer, destinyPropertyName2, linkType))
00182 {
00183 ok = FALSE;
00184 qWarning() << "QVCameraWorker::linkUnspecifiedOutputProperty(): error, can't link U property " << qPrintable(destinyPropertyName2) ;
00185 }
00186 if (destinyContainer->isType< QVImage<uChar, 1> >(destinyPropertyName3))
00187 if(not QVWorker::linkProperty("V channel image", destinyContainer, destinyPropertyName3, linkType))
00188 {
00189 ok = FALSE;
00190 qWarning() << "QVCameraWorker::linkUnspecifiedOutputProperty(): error, can't link V property " << qPrintable(destinyPropertyName3) ;
00191 }
00192
00193 return ok;
00194 }
00195
00196
00197 void QVCameraWorker::grabFrame()
00198 {
00199
00200 if(this->grab(imageY,imageU,imageV))
00201 {
00202 setPropertyValue<int>("Frames",getPropertyValue<int>("Frames")+1);
00203 newGrabbedFrame = TRUE;
00204
00205
00206 if(realTime and not flush_pending_images)
00207 QTimer::singleShot(0, this, SLOT(grabFrame()));
00208 }
00209 else
00210 resetCameraWorker();
00211 }
00212
00213 void QVCameraWorker::iterate()
00214 {
00215
00216
00217 if(getIteration()==0)
00218 tryOpeningCam();
00219
00220
00221 if(isStoped()) return;
00222
00223
00224
00225 if (not realTime)
00226 grabFrame();
00227
00228 setPropertyValue< QVImage<uChar, 1> >("Y channel image", imageY);
00229 setPropertyValue< QVImage<uChar, 1> >("U channel image", imageU);
00230 setPropertyValue< QVImage<uChar, 1> >("V channel image", imageV);
00231 newGrabbedFrame = FALSE;
00232
00233 if (isLinkedOutput("RGB image"))
00234 {
00235 QVImage<uChar, 3> imageRGB(imageY.getCols(),imageY.getRows());
00236 YUV420ToRGB(imageY, imageU, imageV, imageRGB);
00237 setPropertyValue< QVImage<uChar, 3> >("RGB image", imageRGB);
00238 }
00239
00240 }
00241
00242 void QVCameraWorker::processTrigger(QString str)
00243 {
00244 if(str=="Reopen")
00245 {
00246
00247 resetCameraWorker();
00248
00249 readInputProperties();
00250 tryOpeningCam();
00251 }
00252 }