I am very new to android, as I got a project for maintenance. I completed other part of the project like authentication, token setting etc... In that face recognition is used to identify the person. Previously it was working fine and taken images, trained with it and recognized the person.(Obviously not done by me :)). Now it throws error as
Add Person ActivityCvException [org.opencv.core.CvException:
cv::Exception:
/build/master_pack-android/opencv/modules/core/src/matrix.cpp:1047:
error: (-13) The matrix is not continuous, thus its number of rows can
not be changed in function cv::Mat cv::Mat::reshape(int, int) const
Code sample is as follows
public void training() {
Thread thread;
try{
PreferenceManager.setDefaultValues(getApplicationContext(), R.xml.preferences, false);
}catch (Exception e){
AddPersonActivity.this.runOnUiThread(new Runnable() {
public void run() {
WriteLog("Add Person Activity" +e.fillInStackTrace());
errorAlert("Add Person Activity" +e.fillInStackTrace());
VolleyHelper.progressDialog.dismiss();
}
});
}
WriteLog("training 1 ");
final Handler handler = new Handler(Looper.getMainLooper());
thread = new Thread(new Runnable() {
public void run() {
if (!Thread.currentThread().isInterrupted()) {
try {
WriteLog("training 2 ");
PreProcessorFactory ppF = new PreProcessorFactory(AddPersonActivity.this);
PreferencesHelper preferencesHelper = new PreferencesHelper(AddPersonActivity.this);
String algorithm = preferencesHelper.getClassificationMethod();
FileHelper fileHelper = new FileHelper();
fileHelper.createDataFolderIfNotExsiting();
final File[] persons = fileHelper.getTrainingList();
if (persons.length > 0) {
Recognition rec = RecognitionFactory.getRecognitionAlgorithm(getApplicationContext(), Recognition.TRAINING, algorithm);
for (File person : persons) {
if (person.isDirectory()) {
File[] files = person.listFiles();
int counter = 1;
for (File file : files) {
if (FileHelper.isFileAnImage(file)) {
Mat imgRgb = Imgcodecs.imread(file.getAbsolutePath());
Imgproc.cvtColor(imgRgb, imgRgb, Imgproc.COLOR_BGRA2RGBA);
Mat processedImage = new Mat();
imgRgb.copyTo(processedImage);
List<Mat> images = ppF.getProcessedImage(processedImage, PreProcessorFactory.PreprocessingMode.RECOGNITION);
if (images == null || images.size() > 1) {
continue;
} else {
processedImage = images.get(0);
}
if (processedImage.empty()) {
continue;
}
String[] tokens = file.getParent().split("/");
final String name = tokens[tokens.length - 1];
for (int i = 0; i < files.length; i++) {
File myfile = new File(person +
"\\" + files[i].getName());
String long_file_name = files[i].getName();
System.out.println(long_file_name);
System.out.print(long_file_name);
myfile.renameTo(new File(person +
"\\" + long_file_name + "_101" + ".png"));
}
WriteLog("training 3 ");
MatName m = new MatName("processedImage", processedImage);
fileHelper.saveMatToImage(m, FileHelper.DATA_PATH);
rec.addImage(processedImage, name, false);
counter++;
}
}
}
}
try {
if (rec.train()) {
if (zipFileAtPath("/storage/emulated/0/Pictures/facerecognition/training/" + lcode, "/storage/emulated/0/Pictures/facerecognition/data/SVM/" + lcode + ".zip")) {
WriteLog("training 4 ");
if (zipFileAtPath("/storage/emulated/0/Pictures/facerecognition/data/SVM", "/storage/emulated/0/Pictures/facerecognition/" + "SVM_" + lcode + ".zip")) {
WriteLog("training 5 ");
fileupload(getintent.getStringExtra("lcode"));
} else {
Toast.makeText(getApplicationContext(), "No Face Recognised", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "No Face Recognised", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "Try Again", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
WriteLog("Add Person Activity" +e.fillInStackTrace());
errorAlert("Add Person Activity" +e.fillInStackTrace());
}
handler.post(new Runnable() {
#Override
public void run() {
}
});
} else {
Thread.currentThread().interrupt();
}
} catch (Exception e) {
AddPersonActivity.this.runOnUiThread(new Runnable() {
public void run() {
VolleyHelper.progressDialog.dismiss();
WriteLog("Add Person Activity" +e.fillInStackTrace());
errorAlert("Add Person Activity" +e.fillInStackTrace());
}
});
}
}
}
});
thread.start();
}
The input image needs to be stored as a continuous block of bytes in memory. I came to a similar situation, particularly because Android (at least the version I tried) does not seem to store images continuously. 1) Check if the image is continuous using: inputImage.isContinuous(). It returns a bool. It should be true. 2) If the image is not continuous, you can create a copy of the image that it is by creating a clone of the image via inputImage.clone() . Behind the scenes, we are creating a deep copy of the input using the create method, that should guarantee that the new matrix is continuous.
//check image before continuing:
if ( !inputImage.isContinuous() ){
//if the image is not continuous, create a deep copy:
inputImage = inputImage.clone();
}
Related
I have a folder with about 10 images which I like to OCR extract text.
That works excellent for 1 picture, but my java skills are not good enough to implement that for multiple images.
I'm really appreciate if someone could show me a clean solution for that.
Thanks a lot
br Lukas
TextView output1;
ArrayList<Bitmap> bitmapArray = new ArrayList<Bitmap>();
TextRecognizer recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS);
private void OCR_list()
{
String path = Environment.getExternalStorageDirectory().toString()+"/folder_with_images";
File directory = new File(path);
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
output1.setText(output1.getText() + ", " + files[i].getName());
File imgFile = files[i];
if (imgFile.exists()) {
bitmapArray.add(BitmapFactory.decodeFile(imgFile.getAbsolutePath()));
} else {
output1.setText(output1.getText()+"\n Bitmap not found!");
return;
}
}
InputImage image = InputImage.fromBitmap(bitmapArray.get(0), 0);
recognizer.process(image)
.addOnSuccessListener(
new OnSuccessListener<Text>() {
#Override
public void onSuccess(Text texts) {
processTextRecognitionResult(texts);
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
e.printStackTrace();
}
});
Edit:
I solved it now this way, but looks awful:
private void new_Recognition(InputImage image) {
recognizer.process(image)
.addOnSuccessListener(
new OnSuccessListener<Text>() {
#Override
public void onSuccess(Text texts) {
processTextRecognitionResult(texts);
bitmapArray.remove(0);
if (!bitmapArray.isEmpty()) {
InputImage image = InputImage.fromBitmap(bitmapArray.get(0), 0);
new_Recognition(image);
}
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
e.printStackTrace();
}
});
}
You can iterate on inputs directly, and recognition tasks will be queued up and then processed in order internally.
for (Bitmap input : inputs) {
recognizer.process(input)
.addOnSuccessListener(text -> ...)
}
I am trying to write a custom android print service. I have followed the instruction mentioned in the below blog:
https://github.com/zaki50/MyPrintServiceProject
I am able to create a service, which executes a print job. But after the job doesn't print any thing. My question is, what is the localId that we should provide. Is it printer ip, name? Also is there any way to know why the print job doesn't work.
Basically the two methods that I am concerned about are adding onStartPrinterDiscovery and OnPrintJobQueue as mentioned below:
#Override
public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
String str = Settings.Secure.getString(getBaseContext().getContentResolver(), "enabled_print_services");
Log.d("myprinter", "PrinterDiscoverySession#onStartPrinterDiscovery(priorityList: " + priorityList + ") called")
final List<PrinterInfo> printers = new ArrayList<>();
final PrinterId printerId = generatePrinterId("D8:49:2F:64:04:DB");
final PrinterInfo.Builder builder = new PrinterInfo.Builder(printerId, "D8:49:2F:64:04:DB", PrinterInfo.STATUS_IDLE);
PrinterCapabilitiesInfo.Builder capBuilder = new PrinterCapabilitiesInfo.Builder(printerId);
capBuilder.addMediaSize(PrintAttributes.MediaSize.NA_LETTER, true);
capBuilder.addMediaSize(PrintAttributes.MediaSize.NA_LETTER, false);
capBuilder.addResolution(new PrintAttributes.Resolution("resolutionId", "default resolution", 600, 600), true);
capBuilder.setColorModes(PrintAttributes.COLOR_MODE_COLOR | PrintAttributes.COLOR_MODE_MONOCHROME, PrintAttributes.COLOR_MODE_COLOR);
builder.setCapabilities(capBuilder.build());
printers.add(builder.build());
addPrinters(printers);
}
#Override
protected void onPrintJobQueued(PrintJob printJob) {
Log.d("myprinter", "queued: " + printJob.getId().toString());
printJob.start();
//printJob.complete();
final PrintDocument document = printJob.getDocument();
final FileInputStream in = new FileInputStream(document.getData().getFileDescriptor());
try {
final byte[] buffer = new byte[4];
#SuppressWarnings("unused")
final int read = in.read(buffer);
Log.d("myprinter", "first " + buffer.length + "bytes of content: " + toString(buffer));
} catch (IOException e) {
Log.d("myprinter", "", e);
} finally {
try {
in.close();
} catch (IOException e) {
assert true;
}
}
if( printJob.isStarted()){
printJob.complete();
}
}
My Question is what should be printerId(or localId). How do we know if the printjob has succeeded or failed
You can do detection of print job status with other methods in the class:
if( printJob.isStarted() ){
}
else if( printJob.isCompleted() ){
}
else if( printJob.isCancelled() ){
}
else if( printJob.isFailed() ){
}
In addition, the print service has it's own methods listed in the docs:
#Override
protected void onPrintJobQueued(PrintJob printJob) {
Log.d("printer", "queued: " + printJob.getId().toString());
printJob.start();
//...
printJob.complete();
}
#Override
protected void onRequestCancelPrintJob(PrintJob printJob) {
Log.d("printer", "canceled: " + printJob.getId().toString());
printJob.cancel();
}
My Android project has a for loop. When I call this for loop, a runs in the loop until a=9 and then exits out of the loop. But in my code category.size() is 36.
What is incorrect in my code? How can I fix this problem?
for (int a = 0; a < category.size(); a++) {
File ext = Environment.getExternalStorageDirectory();
File target = new File(ext, "Android/data/"+ac.getPackageName()
+"/cache/"+String.valueOf(category.get(a).get("image").hashCode()));
aq.download(category.get(a).get("image"), target, new AjaxCallback<File>() {
public void callback(String url, File file, AjaxStatus status) {
if (file != null) {
}
}
});
ActionItem act = null;
act = new ActionItem(a,category.get(a).get("name").toString(),
Drawable.createFromPath(target.getAbsolutePath()),
category.get(a).get("image").toString());
quickAction.addActionItem(act, category.size());
}
First, Always use try-catch for any DB/server operations:
for (int a = 0; a < category.size(); a++) {
try {
File ext = Environment.getExternalStorageDirectory();
File target = new File(ext, "Android/data/" + ac.getPackageName() + "/cache/" + String.valueOf(category.get(a).get("image").hashCode()));
aq.download(category.get(a).get("image"), target, new AjaxCallback<File>() {
public void callback(String url, File file, AjaxStatus status) {
if (file != null) {
}
}
});
ActionItem act = null;
act = new ActionItem(a, category.get(a).get("name").toString(), Drawable.createFromPath(target.getAbsolutePath()), category.get(a).get("image").toString());
quickAction.addActionItem(act, category.size());
}catch (Exception e){
Log.e("Exception", e.getMessage());
}
}
Second, after doing this, check out the log, it may some exception throwing after that which stops your loop after 9th element.
Check a value first line inside loop like below :
if(a>8){
break;
}
I'm trying to download a list of RemoteFiles in Android using ownCloud. I can download the files perfectly fine but I'd like to notify the user when a file finishes. I'm downloading an entire directory:
#Override
public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
if (operation instanceof ReadRemoteFolderOperation) {
if (result.isSuccess()) {
Toast.makeText(this, "Finished reading folder", Toast.LENGTH_SHORT).show();
for (Object o : result.getData()) {
RemoteFile remoteFile = (RemoteFile) o;
String remotePath = remoteFile.getRemotePath();
File targetDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
"/owncloud_download");
downloadHelper.downloadFile(remoteFile, targetDirectory);
}
}
}
if (operation instanceof DownloadRemoteFileOperation) {
if (result.isSuccess()) {
// Notify the user here that the file finished
}
}
}
I've looked at the ownCloud library source but can't seem to find what a DownloadRemoteFileOperation returns as a result other than a boolean indicating success and an HTTP status code. I thought it might be in result.getLogMessage() but that just gives me an HTTP 200 status. How can I get the name of a file that's finished?
Edit: I also looked at result.getData() but that's null in a DownloadRemoteFileOperation.
Here's my workaround for the time being. I didn't want to modify the ownCloud library source (again) so instead I just do a check in onTransferProgress like so:
#Override
public void onTransferProgress(long rate, long transferred, long total, String fileName) {
if (transferred == total) {
runOnUiThread(new Runnable() {
// do the update here, file name is available
}
}
}
Here's another option. I needed the file being uploaded if the upload failed so I modified the ownCloud library source. This way I could return file names in the RemoteOperationResult.
RemoteOperationResult.java:
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String name) {
fileName = name;
}
DownloadRemoteFileOperation.java
#Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
/// download will be performed to a temporal file, then moved to the final location
File tmpFile = new File(getTmpPath());
/// perform the download
try {
tmpFile.getParentFile().mkdirs();
int status = downloadFile(client, tmpFile);
result = new RemoteOperationResult(isSuccess(status), status,
(mGet != null ? mGet.getResponseHeaders() : null));
Log_OC.i(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " +
result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log_OC.e(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " +
result.getLogMessage(), e);
}
// Added this line
result.setFileName(mRemotePath);
return result;
}
UploadRemoteFileOperation.java:
#Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
try {
// / perform the upload
synchronized (mCancellationRequested) {
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
} else {
mPutMethod = new PutMethod(client.getWebdavUri() +
WebdavUtils.encodePath(mRemotePath));
}
}
int status = uploadFile(client);
if (mForbiddenCharsInServer){
result = new RemoteOperationResult(
RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER);
} else {
result = new RemoteOperationResult(isSuccess(status), status,
(mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
}
} catch (Exception e) {
// TODO something cleaner with cancellations
if (mCancellationRequested.get()) {
result = new RemoteOperationResult(new OperationCancelledException());
} else {
result = new RemoteOperationResult(e);
}
}
// Added this line
result.setFileName(mLocalPath);
return result;
}
I've got a problem. My app keeps crashing when I start it, but the logcat tells me nothing. I've tried try-catch but it still crashes without leaving something.
Here's my MainActivity.java:
public class MainActivity extends Activity
{
TextView logText;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
logText = (TextView) findViewById(R.id.log);
new Thread(new Runnable() {
#Override
public void run()
{
RestClient restClient = new HttpRestClient();
restClient.setUserAgent("IGN Score Joke Bot for /r/circlejerk");
User user = new User(restClient, "(My Username)", "(My Password)");
try
{
user.connect();
}
catch (Exception e)
{
e.printStackTrace();
}
Comments cmts = new Comments(restClient, user);
ExtendedComments exCmts = new ExtendedComments(cmts);
SubmitActions submitActions = new SubmitActions(restClient, user);
Submissions subms = new Submissions(restClient, user);
ExtendedSubmissions exSubms = new ExtendedSubmissions(subms);
boolean alreadyCmted;
while (true)
{
try
{
log("New loop started!");
List<Submission> submList = exSubms.ofSubreddit("circlejerk", SubmissionSort.NEW, 50);
for (Submission subm : submList)
{
List<Comment> cmtList = exCmts.ofSubmission(subm.getIdentifier(), CommentSort.NEW, 50, null);
for (Comment cmt : cmtList)
{
if (cmt.getBody().contains("/u/ign_score_bot score"))
{
alreadyCmted = false;
for (Comment rCmt : cmt.getReplies())
if (rCmt.getAuthor().equals("ign_score_bot"))
{
alreadyCmted = true;
}
if (!alreadyCmted)
{
log("Found Comment by " + cmt.getAuthor() + "! Commenting...");
submitActions.comment(cmt.getFullName(), new Random().nextInt(9) + "." + new Random().nextInt(9) + "/10 for this post/comment - IGN\n" + "Reasons:\n" + showReasons() + "\n\nI'ma unofficial IGN Score Robot for /r/circlejerk. Do not upvote me! Instead message /u/pongo1231 about how shitty this bot is, then message him feedback!");
}
}
}
}
log("Nothing went wrong. Puh! Now a Coffee Break for 30 secs...");
try
{
Thread.sleep(30000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
catch (RetrievalFailedException e)
{
log("Failed getting comment: " + e.getMessage());
}
}
}
}).run();
}
String showReasons()
{
int reasonsNum = new Random().nextInt(10);
String[] reasons = new String[] { "Not enough text", "Too much text",
"Needs more Upvotes", "Needs more Downvotes",
"Needs more Circlejerk", "Not enough jetfuel for steel beams",
"User needs more userness", "Not good enough graphics",
"Needs more colors", "Needs more IGN", "This Bot sucks",
"Needs more Reddit", "*Nonsense*", "Not mainstream enough",
"Not Spacejam enough", "sdwsyxsawdasdaasdwasadassdaas",
"Beep Boop", "Needs to be posted on /r/funny",
"Not enough Wall Of Text", "Needs more Dank" };
StringBuilder builder = new StringBuilder();
for (int i = 0; i < reasonsNum; i++)
{
builder.append("- " + reasons[new Random().nextInt(reasons.length)] + "\n");
}
return builder.toString();
}
void log(final String text)
{
try {
logText.setText(logText.getText() + "\n" + text);
} catch (Exception e) {
System.out.println(e.getCause());
}
}
}
Might it be because of too less heap size? I have got
android:largeHeap="true"
in my AndroidManifest.xml but I'm not sure if it still uses too much resources.
It's not a problem with the internet permissions too, I've got it set in my AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
I've tried to set breakpoints and it seems to crash at the line
restClient.setUserAgent("IGN Score Joke Bot for /r/circlejerk");
Any help would be appreciated!
EDIT: I've found that the logcat says following every time my app crashes:
Error opening /proc/29336/oom_score_adj; errno=2
That's not the package name or something else from my app, but might that be dependent on my app?