YOLOv4 modification - image-processing

I try to use yolov4 for my school project to detect certain fruit seeds, however, I have tried to add in some backgorund images into the dataset, and also try increase the max_batches as well as changing the subdivisions as well. But, all of these do not show me any improve on the accuracy. Can anyone please help me?
Add background images into dataset
Change the max_batches = 5000, 6500, 7000 and 60000. (default is 6000)
Change the subdivisions = 32, 16, 64

Related

How can be series, a bunch of signals, not the single signal input of sequential data be classified by several groups of classification with DL4J?

I have 60 signals sequences samples with length 200 each labeled by 6 label groups, each label is marked with one of 10 values. I'd like to get prediction in each label group on each label when feeding the 200-length or even shorter sample to the network.
I tried to build own network based on https://github.com/eclipse/deeplearning4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/recurrent/seqclassification/UCISequenceClassificationExample.java example, which, however, provides the label padding. I use no padding for the label and I'm getting exception like this:
Exception in thread "main" java.lang.IllegalStateException: Sequence lengths do not match for RnnOutputLayer input and labels:Arrays should be rank 3 with shape [minibatch, size, sequenceLength] - mismatch on dimension 2 (sequence length) - input=[1, 200, 12000] vs. label=[1, 1, 10]
In fact, it is a requirement for the labels to have a time dimension what is 200-long for the features the same as features are. So here I have to do some kind of techniques like zeroes padding in all 6 labels channel. On other hand, the input was wrong, I put all 60*200 there, however it should be [1, 200, 60] there while 6 labels are [1, 200, 10] each.
The thing under the question is in which part of 200-length label I should place the real label value [0], [199] or may be place labels to the typical parts of the signals they are associated with? My trainings that should check this is still in progress. What kind of padding is better? Zeroes padding or the label value padding? Still not clear and can't google out paper explaining what is the best.

clip image results to a ROI in Google Earth Engine

I have developed a time series of sea surface temperatures for a specific region of interest in Google Earth Engine. Running the code below displays the sea surface temperatures from the entire data set
Map.addLayer(BIOT)
// Load an image.
var sst = ee.ImageCollection('NASA/OCEANDATA/MODIS-Aqua/L3SMI').select('sst')
.filterDate('2013-01-01', '2018-01-01')
.filterBounds(BIOT);
print('sst', sst)
var TS1 = Chart.image.series(sst, BIOT,  ee.Reducer.mean(),
1000, 'system:time_start').setOptions({title: 'BIOT SST',vAxis: {title: 'SST
Celsius'},
});
print(TS1);
Map.setCenter(72.25, -6.8, 7); //lat, long, zoom
Map.addLayer (sst, {'min': 23, 'max': 34, 'palette':"0000ff,32cd32,ffff00,ff8c00,ff0000"});
I tried to add the code:
Map.addLayer(sst.clip(BIOT))
To clip the data to a region I have already defined (BIOT) but the image still displays all the data for all regions, rather than the one I have specified. Any ideas? Any help appreciated!
sst is an ImageCollection, which can't be clipped this way. This also means, when you execute Map.addLayer(sst), you're mapping all images within the collection, if they are spatially overlapping, they will cover each other up.
If you still want to do that, and you only need the data from your AOI BIOT anyways, you can add .map(function(image){return image.clip(BIOT)}) when you create your ImageCollection.
// Load an image **collection**.
var sst = ee.ImageCollection('NASA/OCEANDATA/MODIS-Aqua/L3SMI').select('sst')
.filterDate('2013-01-01', '2018-01-01')
.filterBounds(BIOT)
.map(function(image){return image.clip(BIOT)}) ;
This will iterate over each image in the collection and clip it to BIOT.

TCPDF generating a very large format (HUGE) page layout

I need to print an organigram of a large corporation with php/MySQL. The organigram will be boxes with peoples names in them, and there are just over 200. The page will be very wide and long. I want to be able to set the page size to something like 90 inches high by 300 inches wide (The PDF will be printed on an eco-plotter which is usually used to print architectural plans, but can be used to make huge black and white wall posters. I have done this many times using PageMaker/InDesign but never with php). Is it possible to do this with TCPDF and if yes how? If no, any suggestions of how I can do this in php?
Yes, TCPDF is perfectly capable of generating very large PDF documents. If you're rendering a lot of elements, it would likely be a good idea to make sure you have a high memory limit.
I created an example here: Example large format PDF
The key part is providing your own custom page size. Here's what I used in the script that generated this example:
// create new PDF document, I set landscape,
// inches for units, 300 wide and 90 deep
$pdf = new TCPDF('L', 'in', array(300,90), true, 'UTF-8', false);
The rendering part is, of course, then entirely up to you. I just had some fun with some bezier curves and cells with borders set.
//Line from Dot to Tiny
$pdf->Curve(50, 30, 50 + $offsetx, 30, 50 + $offsetx + 1 , 20 + $offsety_down,
60, 20, null, $style);
$pdf->SetXY(60, 20);
$pdf->Cell(20, 10, 'Tiny', 1, 1, 'TLRB', 0, '', 1, 'C', 'C');
If you want to use points for working with your document (which I'd suggest it over inches - it's real easy to accidentally make 1 inch thick lines and such) pass something like the following to the constructor:
Note: points are a physical unit of measure equal to 1/72 of an inch. This is not specifying rendering resolution but the actual physical size of the document. For line definitions you can use partial numbers for your physical units. For example: 0.75 to specify 3/4 of a point.
// create new PDF document, I set landscape,
// pt for units, 300 wide and 90 deep, 72 points per inch.
$pdf = new TCPDF('L', 'pt', array(300*72,90*72), true, 'UTF-8', false);
TCPDF will work with several different types of units. Another option is millimeters, for instance. Methods like SetXY and Curve and so on will then use whatever page unit you had set here.

custom image filter

1.Introduction:
So I want to develop a special filter method for uiimages - my idea is to change from one picture all the colors to black except a certain color, which should keep their appearance.
Images are always nice, so look at this image to get what I'd like to achieve:
2.Explanation:
I'd like to apply a filter (algorithm) that is able to find specific colors in an image. The algorithm must be able to replace all colors that are not matching to the reference colors with e.g "black".
I've developed a simple code that is able to replace specific colors (color ranges with threshold) in any image.
But tbh this solution doesn't seems to be a fast & efficient way at all!
func colorFilter(image: UIImage, findcolor: String, threshold: Int) -> UIImage {
let img: CGImage = image.cgImage!
let context = CGContext(data: nil, width: img.width, height: img.height, bitsPerComponent: 8, bytesPerRow: 4 * img.width, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
context.draw(img, in: CGRect(x: 0, y: 0, width: img.width, height: img.height))
let binaryData = context.data!.assumingMemoryBound(to: UInt8.self),
referenceColor = HEXtoHSL(findcolor) // [h, s, l] integer array
for i in 0..<img.height {
for j in 0..<img.width {
let pixel = 4 * (i * img.width + j)
let pixelColor = RGBtoHSL([Int(binaryData[pixel]), Int(binaryData[pixel+1]), Int(binaryData[pixel+2])]) // [h, s, l] integer array
let distance = calculateHSLDistance(pixelColor, referenceColor) // value between 0 and 100
if (distance > threshold) {
let setValue: UInt8 = 255
binaryData[pixel] = setValue; binaryData[pixel+1] = setValue; binaryData[pixel+2] = setValue; binaryData[pixel+3] = 255
}
}
}
let outputImg = context.makeImage()!
return UIImage(cgImage: outputImg, scale: image.scale, orientation: image.imageOrientation)
}
3.Code Information The code above is working quite fine but is absolutely ineffective. Because of all the calculation (especially color conversion, etc.) this code is taking a LONG (too long) time, so have a look at this screenshot:
My question I'm pretty sure there is a WAY simpler solution of filtering a specific color (with a given threshold #c6456f is similar to #C6476f, ...) instead of looping trough EVERY single pixel to compare it's color.
So what I was thinking about was something like a filter (CIFilter-method) as alternative way to the code on top.
Some Notes
So I do not ask you to post any replies that contain suggestions to use the openCV libary. I would like to develop this "algorithm" exclusively with Swift.
The size of the image from which the screenshot was taken over time had a resolution of 500 * 800px
Thats all
Did you really read this far? - congratulation, however - any help how to speed up my code would be very appreciated! (Maybe theres a better way to get the pixel color instead of looping trough every pixel) Thanks a million in advance :)
First thing to do - profile (measure time consumption of different parts of your function). It often shows that time is spent in some unexpected place, and always suggests where to direct your optimization effort. It doesn't mean that you have to focus on that most time consuming thing though, but it will show you where the time is spent. Unfortunately I'm not familiar with Swift so cannot recommend any specific tool.
Regarding iterating through all pixels - depends on the image structure and your assumptions about input data. I see two cases when you can avoid this:
When there is some optimized data structure built over your image (e.g. some statistics in its areas). That usually makes sense when you process the same image with same (or similar) algorithm with different parameters. If you process every image only once, likely it will not help you.
When you know that the green pixels always exist in a group, so there cannot be an isolated single pixel. In that case you can skip one or more pixels and when you find a green pixel, analyze its neighbourhood.
I do not code on your platform but...
Well I assume your masked areas (with the specific color) are continuous and large enough ... that means you got groups of pixels together with big enough areas (not just few pixels thick stuff). With this assumption you can create a density map for your color. What I mean if min detail size of your specific color stuff is 10 pixels then you can inspect every 8th pixel in each axis speeding up the initial scan ~64 times. And then use the full scan only for regions containing your color. Here is what you have to do:
determine properties
You need to set the step for each axis (how many pixels you can skip without missing your colored zone). Let call this dx,dy.
create density map
simply create 2D array that will hold info if center pixel of region is set with your specific color. so if your image has xs,ys resolution than your map will be:
int mx=xs/dx;
int my=ys/dy;
int map[mx][my],x,y,xx,yy;
for (yy=0,y=dy>>1;y<ys;y+=dy,yy++)
for (xx=0,x=dx>>1;x<xs;x+=dx,xx++)
map[xx][yy]=compare(pixel(x,y) , specific_color)<threshold;
enlarge map set areas
now you should enlarge the set areas in map[][] to neighboring cells because #2 could miss edge of your color region.
process all set regions
for (yy=0;yy<my;yy++)
for (xx=0;xx<mx;xx++)
if (map[xx][yy])
for (y=yy*dy,y<(yy+1)*dy;y++)
for (x=xx*dx,x<(xx+1)*dx;x++)
if (compare(pixel(x,y) , specific_color)>=threshold) pixel(x,y)=0x00000000;
If you want to speed up this even more than you need to detect set map[][] cells that are on edge (have at least one zero neighbor) you can distinquish the cells like:
0 - no specific color is present
1 - inside of color area
2 - edge of color area
That can be done by simply in O(mx*my). After that you need to check for color only the edge regions so:
for (yy=0;yy<my;yy++)
for (xx=0;xx<mx;xx++)
if (map[xx][yy]==2)
{
for (y=yy*dy,y<(yy+1)*dy;y++)
for (x=xx*dx,x<(xx+1)*dx;x++)
if (compare(pixel(x,y) , specific_color)>=threshold) pixel(x,y)=0x00000000;
} else if (map[xx][yy]==0)
{
for (y=yy*dy,y<(yy+1)*dy;y++)
for (x=xx*dx,x<(xx+1)*dx;x++)
pixel(x,y)=0x00000000;
}
This should be even faster. In case your image resolution xs,ys is not a multiple of region size mx,my you should handle the outer edge of image either by zero padding or by special loops for that missing part of image...
btw how long it takes to read and set your whole image?
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
pixel(x,y)=pixel(x,y)^0x00FFFFFF;
if this alone is slow than it means your pixel access is too slow and you should use different api for this. That is very common mistake on Windows GDI platform as people usually use Pixels[][] which is slower than crawling snail. there are other ways like bitlocking/blitting,ScanLine etc so in such case you need to look for something fast on your platform. If you are not able to speed even this stuff than you can not do anything else ... btw what HW is this run on?

Opencv cvHoughCircles-Parameters doubts

I have some doubts about cvHoughCircles parameters. I have an image that has some circles and I want to count them, the count gives me a wrong number of circles.
So I don't know how to choose some function's parameters like:
dp,min_dist,param1,param2,min_radius, max_radius.
I don't know what numbers I use in this parameters. How Can I calculate this?
Choosing the parameters depends on the images you are using. An explanation of the parameters themselves can be found in the reference here
http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html#cv-houghcircles
Using the function with the following parameters
HoughCircles(gray, circles, CV_HOUGH_GRADIENT,2, gray->rows/4, 200, 100, 10, 50);
Will make it search for circles with a dp of 2, a minimum distance between the circles of 1/4 of the image and accumulator values of max 200,100 that determine what to accept as a circle. The 10 and 50 are minimum and maximum radius for the circles to accept.
If you have trouble finding these parameters try to make a test program that attaches these values to sliders so you can see the result on a test image.
Especially param2 is something that is difficult to determine by measuring. Because you know how many circles are in your image you can do a parameter crawl in the following way:
for(int i=0;i<200;i++) {
cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT,2, gray->rows/4, 200, i, 10, 50);
std::cout<<"HoughCircles with param2="<<i<<" gives "<<circles.size()<<" circles"<<endl;
}
I don't know how param1 and 2 are exactly related but you could do the same with a double for loop to find the optimum. The other values need to be measured from the picture. In stead of making a screenshot you can also save this image with the function:
cvSaveImage("image.jpg",gray);
To make sure you are really measuring the exact picture.

Resources