Can I use rectangle images with a convolution neural network in Keras? - neural-network

Say I'd like to use Keras's Convolutional2D function to build a CNN, can the input image be of size [224, 320, 3] instead of something like [224, 224, 3]?
Should I keep my images in their rectangle format or scale them to be square? I've tried making them into squares but the quality is greatly diminished + there is important data around the edges.
If I build it with rectangle input images, will it end up breaking down the line?
I'd also like to attach a decoder onto the end of the CNN to output the images in the same shape (essentially a VAE with rectangle images not squares).

Can I use Conv2D on arbitrary rectangles?
The short answer is yes. One of the big reasons that squares are used is that the math for the maxpooling/strides/padding is easy if it is exactly the same for both height and width. It just makes it easy. In the case of 224, you could use conv2d with padding=same, followed by maxpool several times to decrease both the height and width from 224, to 112, then 56, 28, 14, then finally 7.
When you do that with an input image of 224x320, then the progressing of reductions is as follows: 224x320, 112x160, 56x80, 28x40, 14x20, 7x10. Not a big deal, and it worked out pretty well. If instead the image was 224x300, it wouldn't get far before second dimension didn't divide nicely.
Here is some code in tensorflow for the encoder side of an autoencoder
import tensorflow as tf
import numpy as np
encoder = tf.keras.models.Sequential([
tf.keras.layers.InputLayer([224,320,3]),
tf.keras.layers.Conv2D(filters=16, kernel_size=5, padding='same', activation='tanh'),
tf.keras.layers.MaxPool2D(2),
tf.keras.layers.Conv2D(filters=16, kernel_size=5, padding='same', activation='tanh'),
tf.keras.layers.MaxPool2D(2),
tf.keras.layers.Conv2D(filters=16, kernel_size=5, padding='same', activation='tanh'),
tf.keras.layers.MaxPool2D(2),
tf.keras.layers.Conv2D(filters=16, kernel_size=5, padding='same', activation='tanh'),
tf.keras.layers.MaxPool2D(2),
tf.keras.layers.Conv2D(filters=16, kernel_size=5, padding='same', activation='tanh'),
tf.keras.layers.MaxPool2D(2),
tf.keras.layers.Conv2D(filters=32, kernel_size=5, padding='same', activation='tanh'),
])
data = np.zeros([1,224,320,3], dtype=np.float32)
print( encoder.predict(data).shape )
The output is
(1, 7, 10, 32)
The reverse can be used to make a decoder

Related

How can i get finger-prints through image using flutter

i am using opencv package https://pub.dev/packages/opencv_4 but can not get fingertprints clearly from image.
i am using this function.
Uint8List? _byte = await Cv2.morphologyEx(
pathFrom: CVPathFrom.GALLERY_CAMERA,
pathString: photoFinger.path,
operation: Cv2.COLOR_BayerGB2RGB ,
kernelSize: [30, 30],
);
i have python code using openvcv lib but dont know how to convert it into dart. using openCv dart package.
python code is:
import cv2
# Read the input image
img = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)
# Apply Gaussian blur to remove noise
img = cv2.GaussianBlur(img, (5, 5), 0)
# Apply adaptive thresholding to segment the fingerprint
img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 5)
# Apply morphological operations to remove small objects and fill in gaps
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=1)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=1)
# Estimate the orientation field of the fingerprint
sobel_x = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=3)
theta = cv2.phase(sobel_x, sobel_y)
# Apply non-maximum suppression to thin the ridges
theta_quantized = np.round(theta / (np.pi / 8)) % 8
thin = cv2.ximgproc.thinning(img, thinningType=cv2.ximgproc.THINNING_ZHANGSUEN, thinningIterations=5)
# Extract minutiae points from the fingerprint
minutiae = cv2.ximgproc.getFastFeatureDetector().detect(thin)
# Display the output image with minutiae points
img_with_minutiae = cv2.drawKeypoints(img, minutiae, None, color=(0, 255, 0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('Output Image', img_with_minutiae)
cv2.waitKey(0)
cv2.destroyAllWindows()

How to make a Weibull fit on an existing histogram?

I created a histogram plot based on my datasets. I would like to create a Weibull fit for this histogram.
I used scipy and the stats.weibull function, but unfortunately, it does not work.
Do you have an idea of how to use the stats.weibull in this case?
Here is the code:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
data = 'Figures/Histogram/Histogram.xlsx'
hist= pd.read_excel('Histogram/Histogram.xlsx')
# x= hist['DeltaT_value']
x= hist['DeltaT_-250_2017']
X=x[(x>0)]
plt.figure(figsize=(15,4))
plt.hist(X, bins= np.arange (0,1500,25), color='#0504aa', edgecolor ='red', rwidth= 0.8)
plt.ylabel('Number of EL')
plt.xlabel('Delta T (years CE) between EL')
plt.xlim(0, 401)
plt.xticks(np.arange(0,401,25))
plt.yticks(np.arange(0,2.2,1))`
# Weibull
####
shape, loc, scale = stats.weibull_min.fit(X)
x = np.linspace(stats.weibull_min.ppf(0.01, shape, loc=loc, scale=scale), stats.weibull_min.ppf(0.99, shape, loc=loc, scale=scale), 100)
plt.plot(x, stats.weibull_min.pdf(x, shape, loc=loc, scale=scale), 'r-', lw=5, alpha=0.6, label='weibull')
I tried this:
shape, loc, scale = stats.weibull_min.fit(X)
x = np.linspace(stats.weibull_min.ppf(0.01, shape, loc=loc, scale=scale), stats.weibull_min.ppf(0.99, shape, loc=loc, scale=scale), 100)
plt.plot(x, stats.weibull_min.pdf(x, shape, loc=loc, scale=scale), 'r-', lw=5, alpha=0.6, label='weibull')
Unfortunately, it seems another graph is created on top of the histogram instead of a fit.
After working on it for a little while, I found a solution:
shape, loc, scale = stats.weibull_min.fit(X, floc = 0, f0 = 1)
W = np.linspace(stats.weibull_min.ppf(0.001, shape, loc=loc, scale=scale), stats.weibull_min.ppf(0.99, shape, loc=loc, scale=scale), 1000)
p = stats.weibull_min.pdf(W, shape, scale = scale)
Robert Dodier's comments on my original post are very interesting and I will try to see how I can use a "log likelihood function" on the original dataset rather than a fit on the histogram. This is the first time I will use a log likelihood function. If anyone has some advice, I would gladly take it.
Thanks.
Mat, here's what I get with the approach I was arguing for, which is to work with the likelihood function as derived from quantile data (i.e., the cumulative summation of histogram bars).
I've devised some code for the computer algebra system Maxima (https://maxima.sourceforge.io) to do the calculations. I'll link to the code, but it's probably difficult to use at this point; mostly what I want to say is that this business about working with the likelihood function is a good path forward. See also my comments on this other question about deriving the likelihood function for binned data: https://stats.stackexchange.com/questions/11176/can-anyone-explain-quantile-maximum-probability-estimation-qmpe/442966#442966
The code I'm using is the package robert-dodier/qmpe under https://github.com/maxima-project-on-github/maxima-packages . That in turn makes use of as-yet-unreleased functions (to be released in the next version of Maxima, namely 5.47) from the Maxima package distrib; that unreleased version may be found at https://sourceforge.net/p/maxima/code/ci/master/tree/share/distrib/ .
Looks like the data shown in the histograms is just:
q: [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325];
n: [0, 1, 3, 2, 2, 3, 0, 2, 1, 0, 1, 1, 0, 1];
with q being the quantiles (0, 25, 50, ... 325 years) and n being the number of events in each bin (0, 1, 2, or 3 being the only observed values).
I tried a lognormal distribution and a Weibull distribution. Other distributions are possible by the same method, I just haven't written the code for them yet; I might still try it.
For the lognormal, I get mu = 4.546, sigma = 0.7794, with negative log likelihood nll = 2.528. For the Weibull, I get shape = 1.488, scale = 136.2, with nll = 2.491. Here are figures comparing lognormal to data and Weibull to data. The green line is the final fit; the red line, barely visible in the Weibull plot, is from the initial parameters for the optimization.
As you can see, the Weibull fit is a little better as determined from nll, but neither one is really very good, and in fact it's likely there's no distribution that gives a good fit -- there are only a few data per bin and they're pretty noisy.
As a postscript, here is the code I am working with to generate the figures shown. As I was saying, I don't expect anyone to run this code, it's just to present the general method about working with the likelihood function as derive from the histogram data.
/* inspired by: https://stackoverflow.com/questions/75090377/how-to-make-a-weibull-fit-on-an-existing-histogram */
/* data shown in histogram https://i.stack.imgur.com/uYt70.png
* values appear to be just 0, 1, 2, or 3
*/
q: [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325];
n: [0, 1, 3, 2, 2, 3, 0, 2, 1, 0, 1, 1, 0, 1];
p_unnormalized: makelist (lsum (n1, n1, firstn (n, k)), k, 1, length (n));
p: p_unnormalized / last (p_unnormalized);
load (distrib);
load ("qmpe.mac");
quux: construct_qmpe (cdf_weibull (u, shape, scale), 'u, '[shape, scale], mle_weibull, 1e-4, [1, 0]);
mumble: quux (q, p);
set_plot_option ([svg_file, "./SO-75090377-weibull-fit-compare-cdf.svg"]);
plot_qmpe_comparison_cdf (q, p, cdf_weibull (u, shape, scale), u, '[shape, scale], quantile_weibull (0.99, shape, scale), assoc ('initial, mumble), assoc ('final, mumble));
set_plot_option ([svg_file, "./SO-75090377-weibull-fit-compare-pdf.svg"]);
plot_qmpe_comparison_pdf (q, p, pdf_weibull (u, shape, scale), u, '[shape, scale], quantile_weibull (0.99, shape, scale), assoc ('initial, mumble), assoc ('final, mumble));
foo: construct_qmpe (cdf_lognormal (u, location, scale), 'u, '[location, scale], mle_lognormal, 1e-4, [1, 0]);
baz: foo (q, p);
set_plot_option ([svg_file, "./SO-75090377-lognormal-fit-compare-cdf.svg"]);
plot_qmpe_comparison_cdf (q, p, cdf_lognormal (u, location, scale), u, '[location, scale], quantile_lognormal (0.99, location, scale), assoc ('initial, baz), assoc ('final, baz));
set_plot_option ([svg_file, "./SO-75090377-lognormal-fit-compare-pdf.svg"]);
plot_qmpe_comparison_pdf (q, p, pdf_lognormal (u, location, scale), u, '[location, scale], quantile_lognormal (0.99, location, scale), assoc ('initial, baz), assoc ('final, baz));
ev (assoc ('nll, mumble), assoc ('final, mumble), nouns, numer);
ev (assoc ('nll, baz), assoc ('final, baz), nouns, numer);

UNet Segmentation, chest xray lung segmentation using Unet

I want to segment a chest x ray images for lung using UNet model, I have image dataset in which size of each image is (256, 256). When i am using the Unet model for segment it, it is showing error:
ValueError: Exception encountered when calling layer "model" (type Functional).
Input 0 of layer "conv2d" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (None, 256, 256)
Call arguments received by layer "model" (type Functional):
• inputs=tf.Tensor(shape=(None, 256, 256), dtype=uint8)
• training=True
• mask=None
What is the solution? The UNet model which i am using valid for dimension of (height, width, channel).
`#Build the model
inputs = tf.keras.layers.Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
s = tf.keras.layers.Lambda(lambda x: x / 255)(inputs)
#Contraction path
c1 = tf.keras.layers.Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(s)
c1 = tf.keras.layers.Dropout(0.1)(c1)
c1 = tf.keras.layers.Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(c1)
..........................`
I tried using the Unet with dimension (height, width) in that case it is showing error:
ValueError: Input 0 of layer "conv2d_40" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (None, 256, 256)
Please help, thanks`

How to make custom 'any object' Cascade (.xml) for opencv-python?

I want to make a haar cascade so that I can use it to detect a object in opencv-python.For eg, I want to detect a watch. I tried making a cascade using cascade trainer gui but it isn't giving me expected results.
Well, before training, search through the internet. Maybe the object you want to detect has already been trained, so you don't need to train again.
For example, you want to detect a watch. The haar-file is available here.
So I used the file whether it is working or not, the result is:
Code:
import cv2
w_cascade = cv2.CascadeClassifier('watchcascade10stage.xml')
cap = cv2.VideoCapture(0)
while True:
ret, img = cap.read()
if ret:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
w = w_cascade.detectMultiScale(image=gray,
scaleFactor=1.3
minNeighbors=50)
for (x, y, w, h) in watches:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, 'Watch', (x - w, y - h), font, 0.5, (11, 255, 255), 2, cv2.LINE_AA)
cv2.imshow('img', img)
k = cv2.waitKey(0) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
You can find other tutorial searching through the internet. For instance start with this video
So the thing is Haar Cascade is not a detector or even a classifier. It is a feature extractor IF you are going to use Haar Cascade you will use it in conjunction with SVM (support vector machines) for classification and then implement a sliding window to detect watches.
So the steps are a fallowed.
1 Extract a patch of images using sliding window.
2 pass it to SVM trained on Haar Cascade
3 Draw rect if prediction is true
I recommend this tutorial series https://pythonprogramming.net/haar-cascade-object-detection-python-opencv-tutorial/.please do reach out to me if you still need help.

How to specify edge length in Networkx based off of edge weight

import networkx as nx
import numpy as np
import pylab as plt
#Generate graph with 4 nodes
erdo_graph = nx.erdos_renyi_graph(4, 0.7, directed=False)
#Add edge weights
for u,v,d in erdo_graph.edges(data=True):
d['weight'] = np.random.choice(np.arange(1, 7), p=[0.1, 0.05, 0.05, 0.2,])
#If you want to print out the edge weights:
labels = nx.get_edge_attributes(erdo_graph,'weight')
print("Here are the edge weights: ", labels)
#Following "Networkx Spring Layout with different edge values" link that you supplied:
initialpos = {1:(0,0), 2:(0,3), 3:(0,-1), 4:(5,5)}
pos = nx.spring_layout(erdo_graph, weight='weight', pos=initialpos)
nx.draw_networkx(erdo_graph, pos)
plt.show()
Whenever I try to position the nodes based off of a layout, I expect nodes that are connected by a lower edge weight to be closer to each other, but that doesn't seem to be the case.