How to detect a black frame using mean intensity and remove it from an avi file using imagej? - image-processing

I want to build a plugin with fiji, where I input an avi video/frame sequences of grayscale and output the avi/frames with no black frames (remove them).
I though of recording a macro for that. I downloaded an avi video and imported the frames to fiji. How can i record the process above to give me the results I want?
I am new to Fiji. Thank you in advance

If you are happy with an ImageJ-macro, here is what I would do:
requires( "1.53t" );
path = File.openDialog( "Choose an AVI-file." );
run( "AVI...", "select="+path+" avi="+path+" use" );
cnt = 0;
for ( i=1; i<=nSlices; i++ ) {
setSlice( i );
if ( getValue( "Mean" ) < 1 ) {
run( "Delete Slice" );
cnt++;
}
}
setSlice( 1 );
name = File.getNameWithoutExtension( path );
saveAs( "avi", File.getDirectory( path ) + name + "_woBlank" );
//close();
exit( ""+cnt+" blank frames removed." );

Related

PCD file cannot view color information correctly

Operating System and version: Linux 14.04
I am tried to record PCD file from Kinect v2.
The 3 main libraries I used are OpenCV, PCL , OpenNi
I could record the PCD file successfully, however, when I check the PCD file, the color information only show in a little range and cannot cover all the image. Depth information seems OK.
Part of my code is shown below:
// open device
Device device;
result = device.open( openni::ANY_DEVICE );
CheckOpenNIError( result, "open device" );
// create depth stream
VideoStream oniDepthStream;
result = oniDepthStream.create( device, openni::SENSOR_DEPTH );
CheckOpenNIError( result, "create depth stream" );
// set depth video mode
VideoMode modeDepth;
modeDepth.setResolution( 640, 480 );
modeDepth.setFps( 30 );
modeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );
oniDepthStream.setVideoMode(modeDepth);
// start depth stream
result = oniDepthStream.start();
CheckOpenNIError( result, "start depth stream" );
// create color stream
VideoStream oniColorStream;
result = oniColorStream.create( device, openni::SENSOR_COLOR );
CheckOpenNIError( result, "create color stream" );
// set color video mode
VideoMode modeColor;
modeColor.setResolution( 640, 480 );
modeColor.setFps( 30 );
modeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );
oniColorStream.setVideoMode( modeColor);
// start color stream
result = oniColorStream.start();
CheckOpenNIError( result, "start color stream" );
int count = 0;
while(true)
{
// read frame
if( oniColorStream.readFrame( &oniColorImg ) == STATUS_OK )
{
// convert data into OpenCV type
Mat cvRGBImg( oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData() );
cvtColor( cvRGBImg, cvBGRImg, CV_RGB2BGR );
imshow( "image", cvBGRImg );
}
if( oniDepthStream.readFrame( &oniDepthImg ) == STATUS_OK )
{
Mat cvRawImg16U( oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData() );
cvRawImg16U.convertTo( cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
imshow( "depth", cvDepthImg );
}
cout<< oniDepthImg.getWidth() << " d "<<oniDepthImg.getHeight() <<endl;
cout<< oniColorImg.getHeight()<< " c "<< oniColorImg.getWidth() <<endl;
char input = waitKey(1);
// capture depth and color data
if( input == 'c' )
{
//get data
DepthPixel *pDepth = (DepthPixel*)oniDepthImg.getData();
//create point cloud
cloud.width = oniDepthImg.getWidth();
cloud.height = oniDepthImg.getHeight();
cloud.is_dense = false;
cloud.points.resize(cloud.width * cloud.height);
color_cloud.width = oniDepthImg.getWidth();
color_cloud.height = oniDepthImg.getHeight();
color_cloud.is_dense = false;
color_cloud.points.resize(color_cloud.width * color_cloud.height);
//test = cvCreateImage(cvSize(cloud.width,cloud.height),IPL_DEPTH_8U,3);
IplImage temp11 = (IplImage)cvBGRImg;
//test2 = &IplImage(cvBGRImg);
test2 = &temp11;
for(i=0;i<oniDepthImg.getHeight();i++)
{
for(j=0;j<oniDepthImg.getWidth();j++)
{
float k = i;
float m = j;
xx = pDepth[i*oniDepthImg.getWidth()+j];
CoordinateConverter::convertDepthToWorld (oniDepthStream,m,k,xx,&x,&y,&z);
/* cloud[i*cloud.width+j].x = x/1000;
cloud[i*cloud.width+j].y = y/1000;
cloud[i*cloud.width+j].z = z/1000;
*/
color_cloud[i*cloud.width+j].x = x/1000;
color_cloud[i*cloud.width+j].y = y/1000;
color_cloud[i*cloud.width+j].z = z/1000;
color_cloud[i*cloud.width+j].b = (uint8_t)test2->imageData[i*test2->widthStep+j*3+0];
color_cloud[i*cloud.width+j].g = (uint8_t)test2->imageData[i*test2->widthStep+j*3+1];
color_cloud[i*cloud.width+j].r = (uint8_t)test2->imageData[i*test2->widthStep+j*3+2];
}
}
cout<<"the "<<count<<" is saved"<<endl;
// sprintf(filename,"./data/%d.pcd",count);
// pcl::io::savePCDFileBinaryCompressed(filename,cloud);
// cerr<<"Saved "<<cloud.points.size()<<" data points to xyz pcd."<<endl;
sprintf(filename,"./data/color_%d.pcd",count);
pcl::io::savePCDFileBinaryCompressed(filename,color_cloud);
cerr<<"Saved "<<color_cloud.points.size()<<" data points to xyzrgb pcd."<<endl;
sprintf(filename,"./data/color_%d.jpg",count);
imwrite(filename,cvBGRImg);
sprintf(filename,"./data/depth_%d.jpg",count++);
imwrite(filename,cvDepthImg);
}
}
I output the width and height of oniDepthImg, these are 640 480; the width and height of oniColorImg, these are 1080 1920. I think maybe I lost some color data when I combine them to PCD file.
Does anyone know what the problem is and give me some suggestions?
Any ideas are appreciated!

How to loop through all Symbols and check the current bar and the previous one's High?

The problem is that when the i in the for loop reaches 15, I get an Array out of range error.
What I want to achieve is on every tick to check every Symbol in the MarketWatch and in each Symbol to check the current bar ( PERIOD_M5 ) and the previous one if there is a gap.
void OnTick()
{
int size = ArraySize( Symbols );
for( int i = 0; i < size; i++ )
{
int current_bar_index = iHighest( Symbols[i], PERIOD_M5, MODE_HIGH, 1, 0 );
int previous_bar_index = iHighest( Symbols[i], PERIOD_M5, MODE_HIGH, 1, 1 );
int current_bar_index_low = iLowest( Symbols[i], PERIOD_M5, MODE_LOW, 1, 0 );
int previous_bar_index_low = iLowest( Symbols[i], PERIOD_M5, MODE_LOW, 1, 1 );
double current_high = High[ current_bar_index];
double previous_high = High[previous_bar_index];
double current_low = Low[ current_bar_index_low];
double previous_low = Low[ previous_bar_index_low];
if ( current_low > ( previous_high + 0.00002 )
|| current_high < ( previous_low - 0.00002 )
)
{
Print( "There is a gap" );
}
}
}
Symbols[] is the array containing all the symbols. I loop through it and pass the current Symbol and get the index for the current bar and the previous one and then simply check if there is a gap.
The first problem is that passing every Symbol doesn't work. It gets only one and that's it. How can I achieve that and also, why I get an Array out of range error?
Let's start with the Array out of range error:
Given the MCVE was not present, let's assume, there is some fair declaration of the MQL4 code in the header or something like that.
So to diagnose this, add a trivial debug tool:
string SymbolsARRAY[] = { ..., // be carefull, some Brokers
..., // have quite strange names
...
};
for ( int cellPTR = 0;
cellPTR < ArraySize( SymbolsARRAY );
cellPTR++
)
PrintFormat( "%s[%d] = %s",
"SymbolsARRAY",
cellPTR,
SymbolsARRAY[cellPTR]
);
and post here the output.
Next, the GAP detection:
if you would not mind, checking a pair of M5-Bars for a GAP on each and every price QUOTE message arrival, is quite devastating the MQL4 computing resources. The GAP may principally appear only upon a new Bar starts ( and yet may disappear, during the Bar duration ).
Let's detect the initial GAP-condition ( it is similar to engulfing detection ):
if ( iLow( SymbolsARRAY[cellPTR], PERIOD_M5, 1 ) > iHigh( SymbolsARRAY[cellPTR], PERIOD_M5, 0 )
|| iHigh( SymbolsARRAY[cellPTR], PERIOD_M5, 1 ) < iLow( SymbolsARRAY[cellPTR], PERIOD_M5, 0 )
)
Print( "Initial GAP detected" );
Using this inside a detection of a new bar event may look like this:
void OnTick(){
// -----------------------------------------------------------------
// MINIMALISTIC CONTEXT-AWARE GAP DETECT/REMOVE
// -----------------------------------------------------------------
static bool aCurrentGAP = False;
static datetime aCurrentBAR = Time[0];
if ( aCurrentBAR != Time[0] ){
aCurrentBAR = Time[0];
// testInitGAP .........................present?
aCurrentGAP = testInitialGAP_onNewBarEVENT();
}
else {
if ( aCurrentGAP ){
// testInitGAP .....................disappeared?
aCurrentGAP = testInitialGAP_DISAPPEARED();
}
}
// -----------------------------------------------------------------
// MAIN COMPUTING & TRADING DUTIES OF EA-MQL4-CODE
// -----------------------------------------------------------------
...
}
about the error - when you receive it, it also can see the address of the code that generates it: number of line and symbol number in that line
about Symbol - as you may know, in MQL5 you can select all symbols from the market watch, in MQL4 such option is not available, as far as I remember, so I suspect your array of symbol names is empty or sth like that.
Could you show how you initialized that array? A correct way is the following one:
string Symbol[]={"EURUSD","AUDUSD","GBPUSD"};
also your code doesn't make any sense - when you select iHighest(*,*,*,i,j) - that means that EA-code checks i-elements, starting from j-th element ( 1, 0 ) means a current bar only, ( 1, 1 ) means to select just 1 bar, starting from bar 1, so still only 1 Bar is used.
For that it is much easier to have
double cur_high = iHigh( Symbol[i], 5, 0 ),
prev_high = iHigh( Symbol[i], 5, 1 );

Why [ MetaTrader 4 ] can't write/open a file in windows 10 with the FileWrite() function?

I tried implementing the solutions from this post
Cannot open file on Ubuntu
But to no avail. I keep getting a 5002 error. (failed to open file) after FileWrite()
Even when I try out the example script on https://docs.mql4.com/files/filewrite
I get the same error. I tried running MetaTrader Terminal 4 in administrator mode but to no avail either.Does anyone know a solution to this?
#property version "1.00"
#property strict
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName = "EURUSD"; // Сurrency pair
input ENUM_TIMEFRAMES InpSymbolPeriod = PERIOD_H1; // Time frame
input int InpFastEMAPeriod = 12; // Fast EMA period
input int InpSlowEMAPeriod = 26; // Slow EMA period
input int InpSignalPeriod = 9; // Difference averaging period
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // Price type
//--- parameters for writing data to file
input string InpFileName = "MACD.csv"; // File name
input string InpDirectoryName = "Data"; // Folder name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
bool sign_buff[]; // signal array (true - buy, false - sell)
datetime time_buff[]; // array of signals' appear time
int sign_size=0; // signal array size
double macd_buff[]; // array of indicator values
datetime date_buff[]; // array of indicator dates
int macd_size=0; // size of indicator arrays
//--- set indexing as time series
ArraySetAsSeries( sign_buff, true );
ArraySetAsSeries( time_buff, true );
ArraySetAsSeries( macd_buff, true );
ArraySetAsSeries( date_buff, true );
//--- reset last error code
ResetLastError();
//--- copying the time from last 1000 bars
int copied = CopyTime( NULL, 0, 0, 1000, date_buff );
if ( copied <= 0 )
{ PrintFormat( "Failed to copy time values. Error code = %d", GetLastError() );`
return;
}
//--- prepare macd_buff array
ArrayResize( macd_buff, copied );
//--- copy the values of main line of the iMACD indicator
for ( int i = 0; i< copied; i++ )
{ macd_buff[i] = iMACD( InpSymbolName, InpSymbolPeriod, InpFastEMAPeriod, InpSlowEMAPeriod, InpSignalPeriod, InpAppliedPrice, MODE_MAIN, i );
}
//--- get size
macd_size = ArraySize( macd_buff );
//--- analyze the data and save the indicator signals to the arrays
ArrayResize( sign_buff, macd_size - 1 );
ArrayResize( time_buff, macd_size - 1 );
for ( int i = 1; i < macd_size; i++ )
{
//--- buy signal
if ( macd_buff[i-1] < 0
&& macd_buff[i] >= 0 )
{
sign_buff[sign_size] = true;
time_buff[sign_size] = date_buff[i];
sign_size++;
}
//--- sell signal
if ( macd_buff[i-1] > 0
&& macd_buff[i] <= 0 )
{
sign_buff[sign_size] = false;
time_buff[sign_size] = date_buff[i];
sign_size++;
}
}
//--- open the file for writing the indicator values (if the file is absent, it will be created automatically)
ResetLastError();
int file_handle = FileOpen( InpDirectoryName // aDirNAME
+ "//" // aFileSystemTreeBranchSEPARATOR
+ InpFileName, // aFileNAME
FILE_READ|FILE_WRITE|FILE_CSV // fileIoMODE_FLAGs
);
if ( file_handle != INVALID_HANDLE )
{
PrintFormat( "%s file is available for writing", InpFileName );
PrintFormat( "File path: %s\\Files\\", TerminalInfoString( TERMINAL_DATA_PATH ) );
//--- first, write the number of signals
FileWrite( file_handle, sign_size );
//--- write the time and values of signals to the file
for ( int i = 0; i < sign_size; i++ )
FileWrite( file_handle, time_buff[i], sign_buff[i] );
//--- close the file
FileClose( file_handle );
PrintFormat( "Data is written, %s file is closed", InpFileName );
}
else
PrintFormat( "Failed to open %s file, Error code = %d", InpFileName, GetLastError() );
}
Alt. A)
the algo does not check for a positive presence of an InpDirectoryName node in the filesystem.
Alt. B)
in case the Alt. A) passes, there ought be used a compatible delimiter in aFilePATH + aFileNAME string, i.e. == "\\", ( aFileSystemTreeBranchSEPARATOR ref.: Help for details )
thena fileIO shall take place in \Terminal\Common\Files ( in case a FILE_COMMON bitmask flag was added (used) in the int open_flags parameter),
otherwise,the operations will take place in a (sub)-directory of a MetaTrader Terminal 4 local folder== MQL4\Files ( for a live ExpertAdvisor or Custom Indicator or Script mode of operations )or== MQL4\Tester\Files ( in case of using ExpertAdvisor or Custom Indicatorinside a back-testing framework of MT4 Strategy Tester).

OpenCV Stitcher returns ERR_NEED_MORE_IMGS

I have a problem over here with some simple stitching tool test using OpenCV.
Here s my code:
IplImage *pLeft,
*pRight;
pLeft = cvLoadImage( "left.jpg" );
pRight = cvLoadImage( "right.jpg" );
cv::Mat cvMatLeft( pLeft, true ),
cvMatRight( pRight, true );
std::vector<cv::Mat> imgs;
imgs.push_back( cvMatLeft );
imgs.push_back( cvMatRight );
cv::Mat cvMatOutput;
cv::Stitcher myStitcher = cv::Stitcher::createDefault( true );
cv::Stitcher::Status myStatus = myStitcher.stitch( imgs, cvMatOutput );
I get back the enum ERR_NEED_MORE_IMGS while running this code.
When i debug into the functions called by OpenCV i did recognize the following uncertainty:
stitch( )'s first argument is an cv::InputArray named images. Taking a closer look at it shows, that the arguments sz.width and sz.height are 0.
Further on running through estimateTransform( ) twice the function matchImages( ) is called where the member imgs_ is checked. This one is derived from the InputArray and has (resulting) the size( ) (of images) being 0.
This leads to the mentioned enum.
What am i doing wrong? Something on initialization of the stitcher or the cv::Mat?
Thanks in advance
I think it occurs when you use similar image. When you use the images which the number of extraced feature points is small, so it does.

OpenCV cvWriteFrame , cvWriteToAVI

The problem is as follows
I want to read a video file from disk and convert its every frame into grayscale and write it into new video file
I am using following code to do so
CvCapture* capture = cvCreateFileCapture( "/root/tree.avi");
if (!capture){
return -1;
}
...
CvVideoWriter* writer =
cvCreateVideoWriter("/root/output.avi",CV_FOURCC('D','I','V','X'),fps,size);
...
IplImage* gray_frame = cvCreateImage(
size,
IPL_DEPTH_8U,
1
);
while( (bgr_frame=cvQueryFrame(capture)) != NULL ) {
cvShowImage( "Example2_10", bgr_frame );
cvCvtColor(bgr_frame,gray_frame,CV_RGB2GRAY);
cvShowImage( "B&W result", gray_frame );
cvWriteFrame( writer, gray_frame);
char c = cvWaitKey(10);
if( c == 27 ) break;
}
...
The problem is , program runs fine , but fails to write frames to output.avi and creats only blank output.avi file of just 5.5KB
One more thing is i am unable to write only gra_frame using cvWriteFrame , and if i try to Write bgr_frame , it does write the output.avi file successfully.
Please if anyone knows solution, let me know
You need to pass is_color=0 to the cvCreateVideoWriter function if you want to write gray value images. Because of that you are only able to write color images to your output video.
It is the last parameter of the cvCreateVideoWriter function which defaults to 1:
CvVideoWriter* cvCreateVideoWriter(const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1)
In my case the problem was that I created an a CvVideoWriter in a different resolution than the image I wrote to it using cvWriteFrame. This worked fine in an earlier version of OpenCV, but failed to write frames in OpenCV 2.4

Resources